Using the Dead Letter Queue Handler in WebSphere MQ

Websphere MQ provides the Dead Letter Queue (DLQ) Handler Utility to process undelivered messages, and it can be implemented as a server service object, or triggered whenever a message appears on the DLQ. This article shows you how to implement it both ways in order to help manage messaging with WebSphere MQ.

Varun Gupta (vagupta7@in.ibm.com), WebSphere MQ Technical Services Professional, IBM

Photo of Varun GuptaVarun Gupta is a WebSphere MQ Technical Services Professional with IBM India. He has a Masters Degree in Computer Applications and has five years of IT experience with messaging products such as WebSphere Message Broker and WebSphere MQ. He is an IBM Certified WebSphere MQ Administrator and has been providing WebSphere Message Broker and WebSphere MQ administrative services to clients in the United States. You can contact Varun at vagupta7@in.ibm.com.



18 April 2012

Also available in Russian

Introduction

IBM® WebSphere® MQ is IBM's message-oriented middleware product. It enables independent and potentially non-concurrent applications on a heterogeneous system to communicate with one other, and it is supported on more than 80 different platforms.

One of the strengths of WebSphere MQ is its ability to reliably deliver messages to the destination queue. Of course, configuration or network problems occasionally prevent messages from arriving on the destination queue, in which case they are placed on the Dead Letter Queue (DLQ), along with messages returned form the destination queue. This article describes the DLQ and the DLQ Handler Utility, which processes messages placed on the DLQ.

The DLQ Handler Utility can be configured to run as a server service object, or can be triggered based on criteria set on the DLQ. This article shows you how to configure both scenarios, and explains the advantages and disadvantages of each scenario. Messages can be placed on the DLQ using local put, remote put, or fast channels. This article uses the remote put scenario.

Scenario 1: Configuring the DLQ Handler as a server service object

If the receiver channel is not able to put the message in the destination queue, then those messages are be placed in the DLQ of the remote WebSphere MQ queue manager, provided a DLQ is defined for it. The DLQ Handler is kept waiting for incoming messages on the DLQ. You specify the DLQ to accept undelivered messages using the queue manager menu option Properties => Default dead queue. For example, in Figure 1, the name of the DLQ for undelivered messages for the IBMQMR queue manager is specified as DEADQ:

Figure 1. Name DLQ of queue manager
Name DLQ of queue manager

To run the DLQ handler as a service, you need to define a server service object in that queue manager. This example uses a batch file and rules table for the DLQ Handler. Listing 1 shows the contents of the executable batch file dlqhandler.bat. Four arguments separated by blanks for runmqdlq are being passed, as shown in the STARTARG field of the server service object called dlqhandler in Listing 3.

Listing 1. Contents of dlqhandler.bat
cd "C:\Program Files\IBM\WebSphere MQ\bin"
runmqdlq %1 %2 %3 %4

The rules table should be defined with some REASON and ACTION sequence and WAIT (YES), which means that the DLQ Handler waits indefinitely for further messages to arrive on the DLQ, as shown below in Listing 2. The objective is that whenever an undelivered message arrives on the DLQ, it should get processed by the DLQ Handler using the rules table, which forwards the message to a secondary DLQ, such as DLQX on queue manager IBMQMR. In this first scenario, the DLQ Handler is running as server service object on queue manager IBMQMR.

Listing 2. Contents of rules table RULETBL.RUL
INPUTQ('DEADQ') INPUTQM('IBMQMR') RETRYINT(45) WAIT(YES)
REASON(MQRC_Q_FULL) ACTION(FWD) FWDQ(DLQX) FWDQM(IBMQMR)

In Listing 3 below, under the runmqsc mode, you name the service object and pass on the values to the parameters, such as start command (STARTCMD), start argument (STARTARG), and standard output and error log files (STDOUT and STDERR). For testing purpose CONTROL has been set to MANUAL. The absolute path of the files can be anything that depends on your file system configuration.

Listing 3. Define server service object for DLQ Handler
DEFINE SERVICE(dlqhandler) +
SERVTYPE(SERVER) +
CONTROL(MANUAL) +
STARTCMD('C:\IBM\WebSphere\MQ\dlqhandler.bat') +
DESCR('dead letter queue handler as server service') +
STARTARG('DEADQ IBMQMR < C:\IBM\WebSphere\MQ\RULETBL.RUL') +
STDOUT('C:\IBM\WebSphere\MQ\Log.txt') +
STDERR('C:\IBM\WebSphere\MQ\Err.txt') +
REPLACE

You can set CONTROL to MANUAL, QUEUE MANAGER, or STARTONLY based on your requirements. The value of STARTCMD is the absolute path of the executable file dlqhandler.bat (on Windows), as shown above in the Listing 3. After you have defined the server service object for the DLQ Handler, you need to make sure that group id mqm, user id MUSR_MQADMIN (on Windows) has Read and Executable privileges on the dlqhandler.bat executable file. RULETBL.RUL is the rules table file.

Try to run the server service object, and monitor the IBMQMR queue manager error log files and standard output and error log files that you have specified in STDOUT and STDERR for that DLQ Handler server service object. Listing 4 shows the status of server service object using the MQSC command:

Listing 4. Display status of server service object
display svstatus('dlqhandler')
1 : display svstatus('dlqhandler')
AMQ8632: Display service status details.
     SERVICE(dlqhandler)                     STATUS(RUNNING)
     PID(3396)                               SERVTYPE(SERVER)
     STARTDA(2011-11-22)                     STARTTI(20.54.28)
     CONTROL(MANUAL)
     STARTCMD(C:\IBM\WebSphere\MQ\dlqhandler.bat)
     STARTARG(DEADQ IBMQMR < C:\IBM\WebSphere\MQ\RULETBL.RUL)
     STOPCMD( )                              STOPARG( )
     DESCR(dead letter queue handler as server service)
     STDOUT(C:\IBM\WebSphere\MQ\Log.txt)
     STDERR(C:\IBM\WebSphere\MQ\Err.txt)

After starting the server service object for the DLQ Handler, you will see an entry in the queue manager error log about its startup:

Figure 2. Queue manager error log says DLQ Handler started
Queue manager error log says DLQ Handler started

You will also see IPPROC=1 on the DLQ using WebSphere MQ Explorer, as shown below in Figure 3, with a handle of runmqdlq on the DLQ. You can also check the status of the DLQ using the MQSC command.

Figure 3. DLQ status and its open input count
DLQ status and its open input count

Test Scenario 1 by making the messages to go to the DLQ using a remote put of IBMQMR. Those messages will be processed by the DLQ Handler, which is running as server service object dlqhandler. The rules table file RULETBL.RUL is passed as an argument to the DLQ Handler to process the undelivered messages based on reason/action pairs in it. When the DLQ Handler is running as server service object, it is using CPU resources on the server at all times, which means it always has a handle on the DLQ to process all undelivered messages based on the rules table.

The disadvantage of implementing the DLQ Handler as server service object is that when you try to stop the service on Windows, it will say that you haven't issued the stop command STOPCMD inside the server service object definition, because there are no stop command arguments to end the DLQ Handler as server service object. You will see this problem when the DLQ Handler server service object is defined with CONTROL of QUEUE MANAGER -- in other words, the server service starts and stops only when the respective queue manager starts and stops.

Scenario 2: Triggering the DLQ Handler

Scenario 2 involves setting up the WebSphere MQ trigger facility so that the DLQ Handler runs and processes undelivered messages only when they arrive on the DLQ. To set up Scenario 2, define a process object processdlq within the queue manager IBMQMR that is triggered whenever the trigger conditions are met. Specify the absolute path of the program or process to be triggered in the Application ID field, to avoid unexpected results in the DLQ with the message MQFB_APPL_CANNOT_BE_STARTED.

Listing 5. Queue manager process object definition
display process('processdlq') all
1 : display process('processdlq') all
AMQ8407: Display Process details.
    PROCESS(processdlq)                     APPLTYPE(WINDOWSNT)
    APPLICID(C:\IBM\WebSphere\MQ\dlq_trigger.bat)
    ENVRDATA( )                             USERDATA( )
    DESCR( )                                ALTDATE(2011-11-16)
    ALTTIME(00.43.41)

The process object processdlq has an Application ID field APPLICID and an executable file dlq_trigger.bat. Listing 6 shows the contents of dlq_trigger.bat, where the rules table has been passed to the DLQ Handler:.

Listing 6. Contents of dlq_trigger.bat
cd "C:\Program Files\IBM\WebSphere MQ\bin"
runmqdlq < RULETBL.RUL

As shown in Listing 7 below, the rules table should be defined with a REASON and ACTION sequence with WAIT (NO), which means that the DLQ Handler will not wait indefinitely for further messages to arrive on the DLQ. The control data segment has the input queue and queue manager names:

Listing 7. Contents of rules table RULETBL.RUL
INPUTQ('DEADQ') INPUTQM('IBMQMR') RETRYINT(45) WAIT(NO)
REASON(MQRC_Q_FULL) ACTION(FWD) FWDQ(DLQX) FWDQM(IBMQMR)

Set the Triggering feature ON on this DEADQ of the IBMQMR queue manager, so that whenever a message arrives on DEADQ, DLQ Handler becomes active to handle the message based on the contents of the rules table file RULETBL.RUL. Specify the process name to be triggered as processdlq and the initiation queue as SYSTEM.DEFAULT.INITIATION.QUEUE:

Listing 8. Set the trigger on the DLQ for every incoming message
DEFINE QLOCAL(DEADQ) DESCR('WebSphere MQ Default Dead Letter Queue') 
INITQ(SYSTEM.DEFAULT.INITIATION.QUEUE) TRIGTYPE(EVERY) TRIGGER PROCESS('processdlq')
1 : DEFINE QLOCAL(DEADQ) DESCR('WebSphere MQ Default Dead Letter Queue') 
INITQ(SYSTEM.DEFAULT.INITIATION.QUEUE) TRIGTYPE(EVERY) TRIGGER PROCESS('processdlq')
AMQ8006: WebSphere MQ queue created.
       :
DISPLAY QLOCAL(DEADQ) DESCR INITQ TRIGGER TRIGTYPE PROCESS
2 : DISPLAY QLOCAL(DEADQ) DESCR INITQ TRIGGER TRIGTYPE PROCESS
AMQ8409: Display Queue details.
    QUEUE(DEADQ)                            TYPE(QLOCAL)
    DESCR(WebSphere MQ Default Dead Letter Queue)
    INITQ(SYSTEM.DEFAULT.INITIATION.QUEUE)
    TRIGGER                                 PROCESS(processdlq)
    TRIGTYPE(EVERY)

The trigger monitor program reads the trigger messages of the initiation queue and takes action according to its contents. The queue manager creates the trigger message by copying information from the properties of the process definition object and puts on the initiation queue. You can have the trigger monitor runmqtrm running as server service object or as a background process run from a command prompt. Listing 9 shows how to run the Trigger Monitor runmqtrm from a command prompt:

Listing 9. Run the trigger monitor using the command prompt
runmqtrm -m IBMQMR -i SYSTEM.DEFAULT.INITIATION.QUEUE

Listing 10 below shows a server type service defined with the name triggerdlq as a trigger monitor Service. It is controlled by the queue manager, which starts and stops the service automatically when the queue manager starts and stops. As soon as this service is started, it starts listening for a trigger message to arrive on the initiation queue.

Listing 10. Definition and status of the trigger monitor server service object
display svstatus('triggerdlq') all
1 : display svstatus('triggerdlq') all
AMQ8632: Display service status details.
    SERVICE(triggerdlq)                     STATUS(RUNNING)
    PID(9540)                               SERVTYPE(SERVER)
    STARTDA(2011-12-27)                     STARTTI(17.11.53)
    CONTROL(MANUAL)
    STARTCMD(C:\Program Files\IBM\WebSphere MQ\bin\runmqtrm)
    STARTARG(-m IBMQMR)                     STOPCMD( )
    STOPARG( )                              DESCR(trigger the dlq handler)
    STDOUT(C:\IBM\WebSphere\MQ\Log_runmqtrm.txt)
    STDERR(C:\IBM\WebSphere\MQ\Err_runmqtrm.txt)

If you define a server service object on Windows for MQ utilities like trigger monitor or DLQ Handler with Control as Queue Manager, then to stop those processes, you have to stop the queue manager, which in turn stops the respective server service object. There is no end command for the trigger monitor or DLQ Handler to pass on as a value to the argument STOPCMD of the respective server service object.

The trigger monitor process runmqtrm can be executed using the command prompt as well with arguments for the queue manager name and its initiation queue name.

For testing purposes, make the messages to go to DEADQ of the IBMQMR queue manager, which kicks off the trigger to run the DLQ Handler on every incoming messages, which forwards messages to DLQX according to the rules table shown above. You will see messages on DLQX as the secondary DLQ, IPPROC, OPPROC on DEADQ of IBMQMR after the local queue LOCAL1 is full:

Figure 4. DEADQ and DLQX status after DLQ Handler triggered
DEADQ and DLQX status after DLQ Handler triggered

As soon as a message comes to the DLQ, the DLQ Handler gets triggered and will have a handle on the DLQ to process undelivered messages according to the rules table instructions. The program runmqdlq causes the DLQ Handler to run, and the DLQ Handler runs only when it's been kicked off by trigger monitor. The trigger monitor runs in a different shell that contains the Websphere MQ bin folder in its execution path variable.

Conclusion

In any middleware system involving WebSphere MQ, you should define a DLQ on each queue manager to receive undelivered messages, so that they can be processed and analyzed to determine why they were not delivered to their destinations in a timely manner. The DLQ Handler utility processes the undelivered messages, and can be implemented as either a server service object or as a triggered process. In high-load mission-critical systems, implementing the DLQ Handler as a service object is usually preferable, but in some cases it is better to trigger the DLQ Handler based on custom requirements. This article has explained both scenarios with their pros and cons.

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=810976
ArticleTitle=Using the Dead Letter Queue Handler in WebSphere MQ
publish-date=04182012