Advertisment

Handling Poison Messages With WebSphere MQ

author-image
PCQ Bureau
New Update

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. 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

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

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.

Advertisment

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.

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

Advertisment

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.

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; }}






















Advertisment

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.

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.
Advertisment