Programming considerations

 


Applications can open a queue using the MQOPEN call. Applications use the MQPUT call to put messages onto an open queue. Applications can put a single message onto a queue that is not already open, using the MQPUT1 call.

If you set up clusters that do not have multiple instances of the same queue, there are no specific application programming considerations. However, to benefit from the workload management aspects of clustering, you might need to modify your applications. If you set up a network in which there are multiple definitions of the same queue, review your applications for message affinities as described in Reviewing applications for message affinities.

Also, be aware of the following:

  1. If an application opens a target queue so that it can read messages from it or set its attributes, the MQOPEN call operates only on the local version of the queue.

  2. If an application opens a target queue so that it can write messages to it, the MQOPEN call chooses between all available instances of the queue. Any local version of the queue is chosen in preference to other instances. This might limit the ability of your applications to exploit clustering.

 

Reviewing applications for message affinities

Before starting to use clusters with multiple definitions of the same queue, examine your applications to see whether there are any that have message affinities, that is, they exchange related messages. With clusters, a message can be routed to any queue manager that hosts a copy of the correct queue, affecting the logic of applications with message affinities.

Suppose for example, you have two applications that rely on a series of messages flowing between them in the form of questions and answers. It might be important that all the questions are sent to the same queue manager and that all the answers are sent back to the other queue manager. In this situation, it is important that the workload management routine does not send the messages to any queue manager that just happens to host a copy of the correct queue.

Similarly, you might have applications that require messages to be processed in sequence, for example a file transfer application or database replication application that sends batches of messages that must be retrieved in sequence.

Note:
The use of segmented messages can also cause an affinity problem.

 

Handling message affinities

If you have applications with message affinities, try, to remove the affinities before starting to use clusters.

Removing message affinities improves the availability of applications. If an application that has message affinities sends a batch of messages to a queue manager and the queue manager fails after receiving only part of the batch, the sending queue manager must wait for it to recover before it can send any more messages.

Removing messages affinities also improves the scalability of applications. A batch of messages with affinities can lock resources at the destination queue manager while waiting for subsequent messages. These resources may remain locked for long periods of time, preventing other applications from doing their work.

Furthermore, message affinities prevent the cluster workload management routines from making the best choice of queue manager.

To remove affinities, consider the following possibilities:

  • Carrying state information in the messages

  • Maintaining state information in nonvolatile storage accessible to any queue manager, for example in a DB2 database

  • Replicating read-only data so that it is accessible to more than one queue manager

If it is not appropriate to modify your applications to remove message affinities, there are a number of other possible solutions to the problem. For example, you can:

Name a specific destination on the MQOPEN call
One solution is to specify the remote-queue name and the queue manager name on each MQOPEN call. If you do this, all messages put to the queue using that object handle go to the same queue manager, which might be the local queue manager.

The disadvantages to this technique are:

  • No workload management is carried out. This prevents you from taking advantage of the benefits of cluster workload management.

  • If the target queue manager is remote and there is more than one channel to it, the messages might take different routes and the sequence of messages is still not preserved.

  • If your queue manager has a definition for a transmission queue with the same name as the destination queue manager, messages go on that transmission queue rather than on the cluster transmission queue.

Return the queue-manager name in the reply-to queue manager field
A variation on the first solution is to allow the queue manager that receives the first message in a batch to return its name in its response. It does this using the ReplyToQMgr field of the message descriptor. The queue manager at the sending end can then extract this queue manager name and specify it on all subsequent messages.

The advantage of this method over the previous one is that some workload balancing is carried out to deliver the first message.

The disadvantage of this method is that the first queue manager must wait for a response to its first message and must be prepared to find and use the ReplyToQMgr information before sending subsequent messages. As with the previous method, if there is more than one route to the queue manager, the sequence of the messages might not be preserved.

Use the MQOO_BIND_ON_OPEN option on the MQOPEN call
Another solution is to force all your messages to be put to the same destination, do this using the MQOO_BIND_ON_OPEN option on the MQOPEN call. By opening a queue and specifying MQOO_BIND_ON_OPEN, you force all messages that are sent to this queue to be sent to the same instance of the queue. MQOO_BIND_ON_OPEN binds all messages to the same queue manager and also to the same route. For example, if there is an IP route and a NetBIOS route to the same destination, one of these will be selected when the queue is opened and this selection will be honored for all messages put to the same queue using the object handle obtained.

By specifying MQOO_BIND_ON_OPEN you force all messages to be routed to the same destination. Therefore applications with message affinities are not disrupted. If the destination is not available, the messages remain on the transmission queue until it becomes available again.

MQOO_BIND_ON_OPEN also applies when the queue manager name is specified in the object descriptor when you open a queue. There might be more than one route to the named queue manager (for example, there might be multiple network paths or another queue manager might have defined an alias). If you specify MQOO_BIND_ON_OPEN, a route is selected when the queue is opened.

Note:
This is the recommended technique. However, it does not work in a multi-hop configuration in which a queue manager advertises an alias for a cluster queue. Nor does it help in situations in which applications use different queues on the same queue manager for different groups of messages.

An alternative to specifying MQOO_BIND_ON_OPEN on the MQOPEN call, is to modify your queue definitions. On your queue definitions, specify DEFBIND(OPEN), and allow the MQOO_BIND option on the MQOPEN call to default to MQOO_BIND_AS_Q_DEF. See Queue definition commands for more information about using the DEFBIND attribute in queue definitions.

Use the cluster workload exit
Instead of modifying your applications you can circumvent the message affinities problem by writing a cluster workload exit program. This would not be easy and is not a recommended solution. This program would have to be designed to recognize the affinity by inspecting the content of messages. Having recognized the affinity, the program would have to force the workload management utility to route all related messages to the same queue manager.