设置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)'空或空字符串表示localhost(1414)


在此情况下,设置client reconnect options时,两个选项似乎很重要:


  
  WMQ_CLIENT_RECONNECT-重新连接到连接名称列表中指定的任何队列管理器
  WMQ_CLIENT_RECONNECT_Q_MGR-重新连接到我们最初连接的同一队列管理器。如果尝试连接的队列管理器(在连接名称列表中指定)与原始连接的队列管理器具有不同的QMID,则将抛出MQRC_RECONNECT_QMID_MISMATCH。
  


这些文档不清楚在同一主机/端口后面是否可能有多个队列管理器。与此相比,Oracle可以由同一个侦听器提供多种服务。

我们有两个队列管理器在不同名称的不同主机/端口上侦听。我们想在连接名称列表中使用这些队列管理器之一作为故障转移管理器。问题是:队列管理器是否仅由主机和端口唯一标识?

最佳答案

这个问题有很多要解决的地方,所以让我们一次考虑一个问题。

只能将一个侦听器绑定到特定的端口和接口。因此,如果监听器是混杂的(在所有接口上监听),则每个端口只有一个。如果主机有多个接口,则可以在每个接口的同一端口上绑定单独的侦听器。由于侦听器是队列管理器的子进程,因此仅一个QMgr可以侦听给定的address(port)组合。

QMgr名称不必出现在QMgr收到的连接请求中。如果QMgr名称为空,则前提是QMgr不会因密码错误,证书验证或其他错误而拒绝该连接请求,则该连接将与该连接请求所针对的任何QMgr成功。但是,如果连接请求中包含QMgr名称,则该名称必须与尝试连接的QMgr的名称匹配。

连接名称列表(更恰当地为CONNAME)是用逗号分隔的address(port)组合列表,这些列表有资格接收所请求的连接。

多实例QMgr具有两个地址和一个端口。它们仅在一个地址上处于活动状态,指向它们的通道必须同时具有两个地址才能可靠连接。但是,它不必具有QMgr名称。

但是,还有另一种HA,其中有多个等效的QMgr,每个QMgr具有不同的名称,客户端可以连接到它们。当客户端从记录系统请求信息但本身不是记录系统时,尤其如此。这样的客户端不需要在众所周知的队列上侦听。相反,它连接到客户端连接QMgrs的任一层,创建动态的Reply-To队列,并将请求发送到侦听MQ系统中某个群集队列上的记录系统的记录系统。在这种情况下,客户端没有指定QMgr名称,因此利用了MQ接受其所连接的任何QMgr的行为。

最后,MQ长期以来都有客户端通道定义表或CCDT文件。在使用多实例CONNAME之前,CCDT提供了连接到多个QMgr中的任何一个的功能。 MQ Admin不会将QMgr名称放入CCDT中,而是将符号名称放入。例如,如果有3个用于薪资处理的QMgr,则其CCDT条目中的QMgr名称可能是PAY01,PAY02和PAY03,这些名称均与实际的QMgr名称不匹配。它们每个都有一个address(port)指向三个QMgr之一。然后,开发人员将QMgr名称指定为*PAY,MQ客户端将在所有CCDT条目中选择前三个字符与“ 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服务器支持的最新客户端),请从以下位置下载一个:


SupportPac MQC75
SupportPac MQC8
SupportPac MQC9

关于java - 每个主机/端口是否允许多个队列管理器?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40610245/

10-10 16:50