Using client connections to connect to multiple IBM MQ queue managers

You can configure client connected applications to connect to more than one queue manager (for load balancing or service availability reasons).

The primary mechanisms to achieve this in the IBM® MQ client are use of client channel definition tables, see Configuring client channel definition tables, or connection lists.

It is also possible to achieve similar behavior using external load balancing products or by wrapping IBM MQ connection code in a 'stub' which can redirect host names or IP addresses.

Each of these techniques comes with some restrictions, and might be more or less suitable to particular application requirements. The following sections, although not exhaustive, describe particular aspects you should consider, and the effect of these different approaches on these aspects.

IBM MQ uniform clusters (see About uniform clusters) provide a powerful mechanism to achieve horizontal scaling of applications across multiple queue managers, building on the basic mechanism of the CCDT to provide multiple destinations. Uniform clusters can provide capabilities beyond what is possible by using an external load balancer that is unaware of the underlying IBM MQ protocols, and avoid some of the problems discussed later in this topic, so consider using a uniform cluster in preference to other techniques where applicable.

Attention: Some application environments require particular caution when IBM MQ connections are load balanced. In the following cases, load balancing can cause undefined or unreliable behavior. If you are using load balancing in one of these cases and you contact IBM support for assistance, you might be asked to recreate any problems without the connection redirect.
  • Applications that make multiple connections to the queue manager. Such applications include any that use IBM MQ classes for JMS or IBM MQ classes for Jakarta Messaging because these classes create multiple IBM MQ connections in general usage. If you use an external load balancer or custom code stub, it must always route connections from the same application instance to the same queue manager.
  • Applications that use XA transaction management or the Java Transaction API (JTA). Such applications must always connect or reconnect consistently to the same queue manager. If the load balancing technology that you are using cannot ensure this consistency, you cannot use XA or JTA reliably.
  • Uniform cluster application balancing. This feature relies on being able to instruct clients to reconnect to specific queue managers without interference. So, it is not advisable to attempt to combine external load balancing with the use of uniform clusters

Where possible, consider using IBM MQ uniform clusters instead of external load balancing technologies.

Terms used in this information

CCDT- multi-QMGR
Means a CCDT file that contains multiple client connection (CLNTCONN) channels with the same group, that is the queue manager name client connection (QMNAME CLNTCONN) attribute, where different CLNTCONN entries resolve to different queue managers.
This is distinct from a CCDT file that contains multiple CLNTCONN entries that are simply different IP addresses or host names for the same multi-instance queue manager, which is an approach you might choose to combine with a code stub.
If you do choose a CCDT multi queue manager approach, you need to choose whether to prioritize the entries or have randomized work load management (WLM):
Prioritized
Use multiple alphabetically ordered entries with CLNTWGHT(1) and AFFINITY(PREFERRED) attributes to remember the last good connection.
Randomized
Use CLNTWGHT(1) and AFFINITY(NONE) attributes. You can adjust the WLM weighting across differently scaled IBM MQ servers by adjusting the CLNTWGHT
Note: You should avoid large differences in CLNTWGHT between channels.
Load balancer
Means a network appliance with a Virtual IP address (VIP) configured with port monitoring of the TCP/IP listeners of multiple IBM MQ queue managers. How the VIP is configured in the network appliance depends on the network appliance you are using.

The following choices relate only to applications sending messages, or initiating synchronous request and reply messaging. The considerations for applications servicing those messages and requests, for example, the listeners are completely separate, and discussed in detail in "Connecting a message listener to a queue".

Scale of code change required for existing applications that connect to a single queue manager

CONNAME list, CCDT multi-QMGR, and Load balancer
MQCONN("QMNAME") to MQCONN("*QMNAME")
The queue manager name might be in the Java Naming and Directory Interface (JNDI) configuration for Java Platform, Enterprise Edition (Java EE) applications. Otherwise this requires a one character code-change.
Code stub
Replace existing JMS or MQI connection logic with a code stub.

Support for different WLM strategies

CONNAME list
Prioritized only.
This is likely to have a negative effect on the code.
CCDT multi-QMGR
Prioritized or random.
This is not likely to have any effect on the code.
Load balancer
Any, including each connection for all messages.
This is likely to have a positive effect on the code.
Code stub
Any, including each message for all messages.
This is likely to have a positive effect on the code.

Performance overhead while primary queue manager is unavailable

CONNAME list
Always tries first in list.
This is likely to have a negative effect on the code.
CCDT multi-QMGR
Remembers last good connection.
This is likely to have a positive effect on the code.
Load balancer
Port monitoring avoids bad queue managers.
This is likely to have a positive effect on the code.
Code stub
Can remember last good connection, and retry intelligently.
This is likely to have a positive effect on the code.

XA transaction support

CONNAME list, CCDT multi-QMGR, and Load balancer
The transaction manager needs to store recovery information that reconnects to the same queue manager resource.
An MQCONN call that resolves to different queue managers generally invalidates this. For example, in Java EE, a single connection factory should resolve to a single queue manager when using XA.
This is likely to have a negative effect on the code.
Code stub
Code stub can meet the XA requirements for a transaction manager, for example, multiple connection factories.
This is likely to have a positive effect on the code.

Admin flexibility to hide infrastructure changes from apps

CONNAME list
DNS only.
This is likely to have a negative effect on the code.
CCDT multi-QMGR
DNS and shared file-system, or shared file-system, or CCDT file push.
This is not likely to have any effect on the code.
Load balancer
Dynamic virtual IP address (VIP).
This is likely to have a positive effect on the code.
Code stub
DNS or single queue manager CCDT entries.
This is not likely to have any effect on the code.

Avoiding disruption around planned maintenance

There is another situation that you need to consider and plan for, which is how to avoid disruption to applications, for example, errors and timeouts visible to the end users, during planned maintenance of a queue manager. The best approach to avoid disruption is to remove all work from a queue manager before it is stopped.

Consider a request and reply scenario. You want all in-flight requests to complete, and the replies to be processed by the application, but you do not want any additional work to be submitted into the system. Simply quiescing the queue manager does not fulfill this need, as well-coded applications receive a return code RC2161 MQRC_Q_MGR_QUIESCING exception, before they receive their reply messages for in-flight requests.

You can set PUT(DISABLED) on the request queues used to submit work, while leaving the reply queues both PUT(ENABLED) and GET(ENABLED). In this way, you can monitor the depth of the request, transmission, and reply queues. Once they all stabilize, that is, in-flight requests complete or time out, you can stop the queue manager.

However, good coding in the requesting applications is required to handle a PUT(DISABLED) request queue, which results in the return code RC2051 MQRC_PUT_INHIBITED error, when trying to send a message.

Note that the exception does not occur when creating the connection to IBM MQ, or opening the request queue. The exception occurs only when an attempt is made to actually send a message, using the MQPUT call.

Building a code stub that includes this error handling logic for request and reply scenarios, and asking your application teams to use such a code stub in the future, can help you develop applications with consistent behavior.