Advertisment

Handling poison messages with WebSphere MQ

author-image
CIOL Bureau
Updated On
New Update

BANGALORE, INDIA: Not all messages which are placed on a queue are guaranteed to be processed. Something might go wrong while messages are picked up from the queue by listener programs. For example, consider a scenario when a badly formatted message is dropped on a queue; the application program may not be able to process such a message.

Advertisment

Direct Hit!

Applies To: SOA Developers

USP: Improve application performance by backing out poison messages

Primary Link: http://www.ibm.com/software/integration/wmq

Keywords: WebSphere MQ

The program which de-queues the message backs out the message receipt and places the message back on the queue. Such messages are called poison messages. As the name suggests, a poison message indicates some payload malformation. Furthermore, poison messages may cause deadlocks and badly impact the application performance.

If a poison message is not removed from the queue, the receiving application can get stuck in an infinite loop. WebSpehere MQ provides nifty techniques to handle such poison messages. MQ can re-queue the poison messages on a separate queue (called backout queue) which can be later debugged and cleared. In this article, we'll demonstrate the configuration modifications required for WebSpehere MQ to deal with poison messages and walk through with an application code which shall demonstrate message backout and redelivery.

Advertisment
Configuring MQ backout queue

As discussed, a backout queue is a special type of local queue object which is intended to store poison messages. To begin with, we'll create a local queue named inbound.alerts and a backout queue called failed.payload. The MQ Script Commands (MQSC) required to create the local and backout queue are depicted in figure.

Notice carefully that the runmqsc script command is executed without specifying any queue manager name. WebSphere MQ will choose the default queue manager object- PCQuest. All MQ script commands are then run against the PCQuest queue manager object. We begin by defining two local queues- inbound.alerts and failed.payload. The ALTER QLOCAL script command is then issued to alter properties of the inbound.alerts queue to designate failed.payload as a backout queue.

After running the above mentioned MQ script commands, we'll have the two local queue objects defined and configured. The WebSphere MQ explorer view ID is shown in the figure.

Advertisment

As an administrator, you can configure MQSC commands for creating the backout queue.

Notice that MQ doesn't use any special icon for the backout queue. It's just like any ordinary local queue object. To validate the MQSC commands you can also review the properties of the inbound.alerts queue object, as shown in the figure

Backing out poison messages

For the sake of demonstration, we'll present a code snippet to describe the backout operation and then move the poison message (assuming that the backout counter has reached the threshold value) to the backout queue object.

Advertisment

After running the MQ script commands, we'll have the local queue objects defined and configured.

while (true) {

myMessage.clearMessage();

myMessage.correlationId = MQC.MQCI_NONE;

myMessage.messageId = MQC.MQMI_NONE;

myQueue.get(myMessage, gmo);

//check for the threshold counter

if (myMessage.backoutCount <= boThresh) {

System.out.println("BackoutCount: "

+ myMessage.backoutCount + " of " + boThresh); /*

* increase backout count by one and put the message back on the queue */

qMgr.backout();

} else {

System.out.println ("Message is poison, moving to "+ backoutQueueName);

int openPutOptions = MQC.MQOO_

OUTPUT+ MQC.MQOO_FAIL_ IF_QUIESCING

+ MQC.MQOO_PASS _ALL_CONTEXT;

MQQueue myPutQueue = qMgr.accessQueue (backoutQueueName, openPutOptions, null, null, null);

MQPutMessageOptions pmo = new MQPutMessageOptions();

pmo.options = pmo.options | MQC.MQPMO_SYNCPOINT | MQC.MQPMO _PASS_ALL_CONTEXT;

pmo.contextReference = myQueue;

myPutQueue.put(myMessage, pmo);

/* * close the current transaction and release message(s) held by the syncpoint control */

qMgr.commit();

myPutQueue.close();

break; }}

The program opens the alerts.inbound queue to inquire the backout queue name and the threshold value. The message retrieval operation is wrapped in a transaction. This is done to avoid reading the messages in destructive mode. The program gets the first message on the queue and then backs it out until the backout threshold is reached. The program output is shown in the figure.

Advertisment

These are the Local queue properties. Note that the default threshold value is 5.

Conclusion

If poison messages stay on top of queue, other messages will never get a chance to be de-queued by listener programs. As a matter of practice, if message processing fails, it's always a good idea to retry, but not indefinitely. If messages still fail, messages should be moved out to another queue to be debugged later by an admin. A backout queue offers an excellent buffer for storing such poison messages to let the application run at a normal pace. WebSphere MQ keeps track of number of times a message has been backed out. Once this configurable threshold value is reached, they can be moved to a backout queue. Note that MQ will not automatically move poison messages; it's the responsibility of the application program to move them to a backout queue.

The Eclipse view of the output of sample app. The program gets the first message on the queue and then backs it out until the backout threshold is reached.

tech-news