设置MQQueueConnectionFactory
时,我们按如下方式对其进行初始化:
MQQueueConnectionFactory factory = new MQQueueConnectionFactory();
factory.setQueueManager(queueManager);
factory.setTransportType(CommonConstants.WMQ_CM_CLIENT);
factory.setHostName(host);
factory.setPort(port);
factory.setChannel(channel);
特别是我们设置了队列管理器的名称。从这种模式看,队列管理器名称似乎是完全标识队列管理器所必需的。有人可能会得出结论,在同一主机和端口上,不同的队列管理器可能会监听。这可能吗?
但是,在设置the connection name list以指定重新连接目标时,不需要任何队列管理器名称:
public void setConnectionNameList(java.lang.String hosts) throws javax.jms.JMSException
指定客户端在连接断开后将尝试重新连接到的主机。连接名称列表是主机/ IP端口对的逗号分隔列表。例如。 127.0.0.1(1414),host2.example.com(1400)此属性的默认设置为“localhost(1414)”null或空字符串表示localhost(1414)
在此背景下设置client reconnect options两个选项似乎很重要:
- WMQ_CLIENT_RECONNECT - 重新连接到连接名称列表中指定的任何队列管理器
- WMQ_CLIENT_RECONNECT_Q_MGR - 重新连接到我们最初连接的同一个队列管理器。如果它尝试连接的队列管理器(在连接名称列表中指定)与最初连接到的队列管理器具有不同的QMID,则会抛出MQRC_RECONNECT_QMID_MISMATCH。
这些文档不清楚是否可能在同一主机/端口后面有多个队列管理器。将此与Oracle进行比较,其中同一个侦听器可以提供多种服务。
我们有两个队列管理器侦听具有不同名称的不同主机/端口。我们希望在连接名称列表中使用其中一个队列管理器作为故障转移管理器。问题是:队列管理器是否仅由主机和端口唯一标识?
答案 0 :(得分:3)
在这个问题中有很多东西要放松,所以让我们一次拿一个项目。
只能有一个侦听器绑定到特定端口和接口。因此,如果侦听器是混杂的(侦听所有接口),那么每个端口只有一个。如果主机具有多个接口,则可以在每个接口上的相同端口上绑定单独的侦听器。由于侦听器是队列管理器的子进程,因此暗示只有一个QMgr可以侦听给定的address(port)
组合。
QMgr名称不需要出现在QMgr收到的连接请求中。如果QMgr名称为空,则连接将成功解决连接请求所针对的任何QMgr,前提是QMgr不会因错误密码,证书验证或其他错误而拒绝该连接请求。但是,如果连接请求中的QMgr名称 ,则必须匹配尝试连接的QMgr的名称。
连接名称列表(更恰当CONNAME
)是一个以逗号分隔的address(port)
组合列表,有资格接收所请求的连接。
多实例QMgrs有两个地址和一个端口。它们只在一个地址上激活,指向它们的通道必须具有两个地址才能可靠连接。但是,它不需要具有QMgr名称。
但是还有另一种类型的HA,其中有多个等效的QMgrs,每个都有不同的名称,客户端可以连接到这些QMgrs。当客户端从记录系统请求信息但本身不是记录系统时尤其如此。这样的客户端不需要监听一个众所周知的队列。相反,它连接到一层客户端连接QMgrs中的任何一个,创建一个动态的Reply-To队列,并将请求发送到在某个MQ网络中的集群队列上侦听的记录系统。在这种情况下,客户端没有指定QMgr名称,因此利用了MQ接受它连接的任何QMgr的行为。
最后,MQ一直有客户端通道定义表或CCDT文件。在我们有多实例CONNAME
之前,CCDT提供了连接到几个QMgrs中的任何一个的能力。 MQ Admin不是在CCDT中放置QMgr名称,而是放置符号名称。例如,如果有3个QMgrs用于工资核算处理,则其CCDT条目中的QMgr名称可能是PAY01,PAY02和PAY03,它们都不匹配实际的QMgr名称。其中每个都有一个address(port)
指向三个QMgrs中的一个。然后,开发人员指定QMgr名称*PAY
,MQ客户端将在所有CCDT条目中选择前3个字符匹配' PAY'。通过这个和其他一些选项,可以让MQ客户端驱动器重新连接,但是MQ客户端存根封装了是否在目的地之间循环,重试最后连接的地址等等的逻辑。
从这种模式看,队列管理器名称似乎是必需的 完全识别队列管理器。有人可能会在同一个问题上得出结论 主机和端口不同的队列管理器可能会监听。这是 可能的?
没有
我们有两个队列管理器在不同的主机/端口上监听 有不同的名字。我们想要使用其中一个队列管理器 连接名称列表中的故障转移管理器。问题是:是 队列管理器仅由主机和端口唯一标识?
确保请求中的QMgr名称为空白,并在address(port)
中指定CONNAME
个组合,您应该很高兴。
请参阅:Role of the client channel definition table,特别是该部分Queue manager groups in the CCDT。 Examples of channel weighting and affinity部分在此处也很有帮助。
最后,请确保您使用的是现代客户端。由于MQ客户端可以连接到任何前向或后级QMgr,因此可以在v9.0客户端上进行开发并连接到v7.1 QMgr。当然,所提供的功能基于最低版本的客户端或QMgr,因此您无法通过v9.0客户端和古老的QMgr获得JMS 1.2功能。但是,您做会在以后的客户端版本中获得所有性能改进和错误修复。如果您不是最新的客户端(或JEE服务器支持的最新客户端),请在以下位置下载:
答案 1 :(得分:1)
就像侦听唯一TCP端口的任何其他服务器应用程序一样,IBM MQ Queue Manager侦听主机上的唯一TCP端口。因此,没有两个队列管理器可以在主机上的同一端口上侦听。连接到队列管理器需要主机和端口的组合(简称为连接名称或简称CONNAME)。
连接名称列表用于指定多个主机&港口。在活动队列管理器关闭的情况下,MQ客户机使用此信息自动重新连接到多实例队列管理器或备份队列管理器的备用实例。
来到您的场景:您可以在连接工厂中省略队列管理器名称,只需通过setConnectionNameList方法指定多个主机/端口组合。非常重要:您必须确保两个队列管理器都具有相同的对象定义,如服务器连接通道,以便连接应用程序,队列/主题,权限等。否则您的应用程序可能会失败。