2
votes

When setting up a MQQueueConnectionFactory we initialize it as follows:

MQQueueConnectionFactory factory = new MQQueueConnectionFactory();

factory.setQueueManager(queueManager);

factory.setTransportType(CommonConstants.WMQ_CM_CLIENT);
factory.setHostName(host);
factory.setPort(port);
factory.setChannel(channel);

Especially we set the name of the queue manager. From this pattern it seems that the queue manager name is necessary to fully identify the queue manager. One might concluded that on the same host and port a different queue manager might listen. Is this possible?

However, when setting the the connection name list to specify reconnect targets there is no queue manager name necessary:

public void setConnectionNameList(java.lang.String hosts) throws javax.jms.JMSException

Specifies the hosts to which the client will attempt to reconnect to after its connection is broken. The connection name list is a comma seperated list of host/ip port pairs. eg. 127.0.0.1(1414),host2.example.com(1400) The default setting of this property is 'localhost(1414)' A null, or empty string is taken to mean localhost(1414)

When setting the client reconnect options two options seems to be important in this context:

  • WMQ_CLIENT_RECONNECT - Reconnect to the any of the queue managers specified in the connection name list
  • WMQ_CLIENT_RECONNECT_Q_MGR - Reconnect to the same queue manager we were originally connected to. This will throw MQRC_RECONNECT_QMID_MISMATCH if the queue manager it tries to connect to (specified in the connection name list) has a different QMID to the queue manager originally connected to.

These documentations make not clear if multiple queue managers behind the same host/port are possible. Compare this to Oracle where multiple services can be served by the same listener.

We have two queue managers listening on different hosts/ports which have different names. We want to use one of these queue managers as failover manager in the connection name list. The question is: is the queue manager uniquely identified by host and port only?

2
Thanks for the vote and accept. Please note the updates made later with pointers to the relevant doc links. The CCDT groups are mainly what the generic QMgr names are needed for so is good to understand even if it isn't used.T.Rob

2 Answers

3
votes

There's a lot to unwind in this question so let's take it one item at a time.

There can be only one listener bound to a particular port and interface. So if the listener is promiscuous (listens on all interfaces) there's only one per port. If the host has multiple interfaces separate listeners can be bound on the same port on each of the interfaces. Since a listener is a child process of the queue manager, the implication is only one QMgr can listen on a given address(port) combination.

The QMgr name need not be present in the connection request received by the QMgr. If the QMgr name is blank, the connection succeeds with any QMgr to which the connection request is addressed, provided that QMgr does not reject it for bad password, certificate validation or other errors. However, if a QMgr name is in the connection request it must match the name of the QMgr to which the connection is attempted.

Connection Namelist (more properly CONNAME)is a comma-separated list of address(port) combinations that are eligible to receive the connection being requested.

Multi-Instance QMgrs have two addresses and one port. They are only ever active on one address and a channel pointing to them must have both addresses to be able to connect reliably. However, it need not have the QMgr name.

But there is another type of HA in which there are multiple equivalent QMgrs, each with different names, to which a client can connect. This is especially true when the client is requesting information from a system of record but is not itself a system of record. Such a client has no need to listen on a well known queue. Instead it connects to any one of a tier of client-connection QMgrs, creates a dynamic Reply-To queue, and sends requests out to the system of record listening on a clustered queue out in the MQ network somewhere. In this scenario, the client doesn't specify a QMgr name and thus takes advantage of MQ's behavior of accepting whatever QMgr it connects to.

Finally, MQ has long had Client Channel Definition Table or CCDT files. Before we had multi-instance CONNAME the CCDT provided the capability of connecting to any of several QMgrs. Rather than putting a QMgr name in the CCDT the MQ Admin put symbolic names. For example if there were 3 QMgrs for Payroll processing, the QMgr names in their CCDT entries might be PAY01, PAY02, and PAY03, none of which match the actual QMgr names. Each of these has an address(port) pointing to one of the three QMgrs. The developer then specifies a QMgr name of *PAY and the MQ client would pick among all CCDT entries with the first 3 characters matching 'PAY'. With this and a few other options it was possible to have the MQ client drive reconnects but have the MQ client stub encapsulate the logic of whether to round-robin among destinations, retry the last connected address, or whatever.

From this pattern it seems that the queue manager name is necessary to fully identify the queue manager. One might concluded that on the same host and port a different queue manager might listen. Is this possible?

No.

We have two queue managers listening on different hosts/ports which have different names. We want to use one of these queue managers as failover manager in the connection name list. The question is: is the queue manager uniquely identified by host and port only?

Make sure the QMgr name is blank on the request and specify both address(port) combinations in the CONNAME and you should be good to go.

Please see: Role of the client channel definition table, and in particular in that section Queue manager groups in the CCDT. The section on Examples of channel weighting and affinity is also helpful here.

Finally, be sure that you are using a modern client. Since MQ clients can connect to any forward- or back-level QMgr it is possible to develop on a v9.0 client and connect to a v7.1 QMgr. Of course the functionality provided is based on the lowest version of client or QMgr so you don't get JMS 1.2 features with a v9.0 client and an ancient QMgr. However, you do get all the performance improvements and bug fixes in the later client versions. If you are not at the latest client (or the latest one supported by your JEE server) then go download one at:

1
votes

Just like any other server application listening on a unique TCP port, IBM MQ Queue Manager listens on a unique TCP port on a host. So no two queue managers can listen on the same port on a host. A combination of host and port (a.k.a connection name or CONNAME for short) is required to connect to a queue manager.

A connection name list is used to specify multiple host & port. MQ clients use this information to automatically reconnect to a stand-by instance of multi-instance queue manager or backup queue manager in the event of active queue manager going down.

Coming to your scenario: You can leave out the queue manager name in the connection factory and simply specify the multiple host/port combination via setConnectionNameList method. Very important: You must ensure that both queue managers have same object definitions like server connection channel for application to connect, queues/topics, authorities etc. Otherwise your application may fail.