Handling message affinities
Message affinities are rarely part of good programming design. You need to remove message affinities to use clustering fully. If you cannot remove message affinities, you can force related messages to be delivered using the same channel and to the same queue manager.
If you have applications with message affinities, remove the affinities before starting to use clusters.
Removing message affinities improves the availability of applications. An application sends a batch of messages that has message affinities to a queue manager. The queue manager fails after receiving only part of the batch. The sending queue manager must wait for it to recover and process the incomplete message batch 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 might 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.
- 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 possible solutions to the problem.
Name a specific destination on the MQOPEN call
Specify the remote-queue name and the queue manager name on each MQOPEN call, and all messages put to the queue using that object handle go to the same queue manager, which might be the local queue manager.- No workload balancing is carried out. You do not take advantage of the benefits of cluster workload balancing.
- 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
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 the reply-to queue manager name and specify it on all subsequent messages.- The requesting queue manager must wait for a response to its first message
- You must write additional code to find and use the ReplyToQMgr information before sending subsequent messages
- If there is more than one route to the queue manager, the sequence of the messages might not be preserved
Set the MQOO_BIND_ON_OPEN
option on the MQOPEN call
Force all your messages to be put to the same destination using the MQOO_BIND_ON_OPEN
option on the MQOPEN call. Either MQOO_BIND_ON_OPEN
or MQOO_BIND_ON_GROUP
must be specified when using message groups with clusters to ensure that all messages in the group are processed at the same destination.
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 is selected when the queue is opened and this selection is 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.
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 DefBind option on the MQOPEN call to default to MQOO_BIND_AS_Q_DEF
.
Set the MQOO_BIND_ON_GROUP
option on the MQOPEN call
Force all your messages in a group to be put to the same destination using the MQOO_BIND_ON_GROUP
option on the MQOPEN call. Either MQOO_BIND_ON_OPEN
or MQOO_BIND_ON_GROUP
must be specified when using message groups with clusters to ensure that all messages in the group are processed at the same destination.
By opening a queue and specifying MQOO_BIND_ON_GROUP
, you force all messages in a group that are sent to this queue to be sent to the same instance of the queue. MQOO_BIND_ON_GROUP
binds all messages in a group 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 is selected when the queue is opened and this selection is honored for all messages in a group put to the same queue using the object handle obtained.
By specifying MQOO_BIND_ON_GROUP
you force all messages in a group 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_GROUP
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_GROUP
, a route is selected when the queue is opened.
MQOO_BIND_ON_GROUP
to be effective you must include the
MQPMO_LOGICAL_ORDER put option on MQPUT. You can set GroupId
in the MQMD of the message to MQGI_NONE, and you must include the following message
flags within the MQMD MsgFlags field of the messages:- Last message in group: MQMF_LAST_MSG_IN_GROUP
- All other messages in group: MQMF_MSG_IN_GROUP
If MQOO_BIND_ON_GROUP
is specified but the messages are not grouped, the behavior is equivalent to MQOO_BIND_NOT_FIXED.
An alternative to specifying MQOO_BIND_ON_GROUP
on the MQOPEN call, is to modify your queue definitions. On your queue definitions, specify DEFBIND(GROUP)
, and allow the DefBind option on the MQOPEN call to default to MQOO_BIND_AS_Q_DEF
.
Write a customized cluster workload exit program
Instead of modifying your applications you can circumvent the message affinities problem by writing a cluster workload exit program. Writing a cluster workload exit program is not easy and is not a recommended solution. The 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.