Tuesday, January 21, 2014

MQ Triggering

WebSphere MQ TriggeringWebSphere MQ provides a feature that enables an application or channel to be started automatically when there are messages available to retrieve from a queue.

Trigger messages generated by the queue manager are not persistent. This has the effect of reducing logging (thereby improving performance), and minimizing duplicates during restart, so improving restart time.

Initiation queue:
A local queue on which the queue manager puts trigger messages.

Trigger event: 
An event (such as a message arriving on a queue) that causes a queue manager to create a trigger message on an initiation queue.

Trigger message: 
A message containing information about the program that a trigger monitor is to start.

Trigger monitor: 
A continuously-running application serving one or more initiation queues. When a trigger message arrives on an initiation queue, the trigger monitor retrieves the message. It uses the information in the trigger message to start a process that serves the queue on which a trigger event occurred.

Trigger monitor interface (TMI):
The MQSeries interface to which customer- or vendor-written trigger monitor programs must conform. A part of the MQSeries Framework.

Types of triggering:
1. Channel Triggering 
2. Application Triggering
3. Client Triggering

Before your application can take advantage of triggering, follow the steps below:

1. Create an initiation queue for your application queue. For example:
 DEFINE QLOCAL (initiation.queue) REPLACE +
 LIKE (SYSTEM.DEFAULT.LOCAL.QUEUE) +
 DESCR ('initiation queue description')

2. Associate the initiation queue with the application queue. A queue manager can own more than one initiation queue. You may want some of your application queues to be served by different programs, in which case you could use one initiation queue for each serving program, although you do not have to. Here is an example of how to create an application queue:
 DEFINE QLOCAL (application.queue) REPLACE +
 LIKE (SYSTEM.DEFAULT.LOCAL.QUEUE) +
 DESCR ('appl queue description') +
 INITQ ('initiation.queue') +
 PROCESS ('process.name') +
 TRIGGER +
 TRIGTYPE (FIRST)

3. If you are triggering an application, create a process definition object to contain information relating to the application that is to serve your application queue. For example, to trigger-start a CICS payroll transaction called PAYR:
 DEFINE PROCESS (process.name) +
 REPLACE +
 DESCR ('process description') +
 APPLTYPE ('CICS') +
 APPLICID ('PAYR') +
 USERDATA ('Payroll data')
When the queue manager creates a trigger message, it copies information from the attributes of the process definition object into the trigger message.

4. You need to create a process definition if you want to trigger a channel and you are using a Version 2 MQSeries product. Otherwise, you can create a transmission queue definition and use blanks for the ProcessName attribute. The TrigData attribute can contain the name of the channel to be triggered or it can be left blank. Except on WebSphere MQ for z/OS, if it is left blank, the channel initiator searches the channel definition files until it finds a channel that is associated with the named transmission queue. When the queue manager creates a trigger message, it copies information from the TrigData attribute of the transmission queue definition into the trigger message.

5. If you have created a process definition object to specify properties of the application that is to serve your application queue, associate the process object with your application queue by naming it in the ProcessName attribute of the queue.

6. Start instances of the trigger monitors (or trigger servers in WebSphere MQ for iSeries) that are to serve the initiation queues you have defined.

==>DEFINE QLOCAL(QM2.XMITQ) TRIGGER INITQ(SYSTEM.CHANNEL.INITQ) PROCESS(P1) USAGE (XMITQ)
==>DEFINE PROCESS(P1) USERDATA(QM2.XMITQ)

The figure is a diagram showing a configuration of WebSphere MQ objects and applications, and a sequence of events. The configuration shows a queue manager managing an application queue and an initiation queue. The application queue has an associated process definition object. Three applications, as follows: Application A which can be on a remote system or local to the queue manager. Application B local to the queue manager. Trigger monitor running local to the queue manager. The sequence of events is described in the text following the figure.




This figure shows a more complex configuration of objects and applications. The configuration is as follows: A queue manager managing two application queues with associated process definition objects, called application queue 1 and 2 and process definition object 1 and 2. An initiation queue. Two sets of applications which can be remote or local to the queue manager. The applications are identified as Applications A, B, and C; and Applications X, and Y. A trigger monitor application running local to the queue manager. Two applications started by triggering running local to the queue manager, identified as Applications K, and L.


Troubleshooting:

1. Triggering must be enabled, and of the correct type:
CHECK:
Display the TRIGGER TRIGTYPE and TRIGDPTH attributes of the queue to determine the type of triggering that is enabled:
DIS QL(TRIGGERED_QUEUE) TRIGGER TRIGTYPE TRIGDPTH
Sample output:
AMQ8409: Display Queue details. 
   QUEUE(TRIGGERED_QUEUE)                  TYPE(QLOCAL) 
   TRIGGER                                 TRIGDPTH(1) 
   TRIGTYPE(FIRST)

ACTION:
If NOTRIGGER is seen in the output, then triggering is disabled. Enable it as follows:
ALTER QL(TRIGGERED_QUEUE) TRIGGER
In most cases you can expect the type of triggering (TRIGTYPE) to be FIRST.
A summary of the three types is as follows:
EVERY
Trigger events occur every time a message is delivered to the queue. This occurs even if applications already have the queue open to retrieve messages.
FIRST
Trigger event occur when the depth of the queue transitions from zero to one.
DEPTH
Trigger events occur when the depth of the queue transitions from
(TRIGDPTH-1) to TRIGDPTH.
Triggering is automatically disabled on the queue, and must be re-enabled by the application (using MQSET).

2. No application can already have the queue open to get messages:
This only applies to FIRST or DEPTH triggering.
For EVERY triggering, a trigger event occurs every time a message arrives, regardless of how many applications are already actively retrieving messages from the queue.

CHECK:
Check the IPPROCS attribute in the QSTATUS for the initiation queue:
DIS QS(TRIGGERED_QUEUE) IPPROCS

Sample Output:
AMQ8450: Display queue status details. 
   QUEUE(TRIGGERED_QUEUE) 
   TYPE(QUEUE)                             CURDEPTH(0) 
   IPPROCS(0)

You can find which application has the queue open (IPPROCS>0) as follows:
DIS QS(TRIGGERED_QUEUE) TYPE(HANDLE) APPLTAG PID
Sample Output:
AMQ8450: Display queue status details. 
   QUEUE(TRIGGERED_QUEUE) 
   TYPE(HANDLE) 
   APPLTAG(/home/myuser/bin/mycmd) PID(1234)

ACTION:
For FIRST or DEPTH triggering, if the IPPROCS number is any number greater than zero, then an application has the queue open to retrieve messages and triggering will not occur.
If the application is not the one expected to run against this queue, then it must end before the intended application can be triggered.
The name and PID of the application is shown in the QSTATUS output. If the name contains ‘amqcrsta’ or ‘amqrmppa’, then a remote client application has the queue open (this could be an administrator on another machine).
If an ‘amqrmppa’ process is terminated (kill -9 PID), this will shut down any other channels running within that process.

If the application connected to the queue is the triggered application for this queue, then the application team should be involved to investigate why the application is failing to process messages from the queue.

3. The initiation queue must be valid:
CHECK:
Display the INITQ attribute of the triggered queue:
DIS QL(TRIGGERED_QUEUE) INITQ
Sample Output:
AMQ8409: Display Queue details. 
  QUEUE(TRIGGERED_QUEUE)                    TYPE(QLOCAL) 
  INITQ(SYSTEM.DEFAULT.INITIATION.QUEUE)
Display the initiation queue to check it exists, is not an XMITQ, and is not inhibited for put or get:
DIS QL(SYSTEM.DEFAULT.INITIATION.QUEUE) USAGE PUT GET
Sample Output:
AMQ8409: Display Queue details. 
   QUEUE(SYSTEM.DEFAULT.INITIATION.QUEUE) 
   TYPE(QLOCAL)                      GET(ENABLED) 
   PUT(ENABLED)                      USAGE(NORMAL)
Remember to use single ticks for queues with lower case names:
DIS QL('inititaion.queue') USAGE PUT GET

ACTION:
If the INITQ attribute is blank, or incorrect, then change it to the name of the initiation queue against which the trigger monitor will run.
If the initiation queue is inhibited for put, then enable it as follows:
ALTER QL(SYSTEM.DEFAULT.INITIATION.QUEUE) PUT(ENABLED)

4. A trigger monitor must be active against the initiation queue:
CHECK:
Check the IPPROCS attribute in the QSTATUS for the initiation queue:
DIS QS(SYSTEM.DEFAULT.INITIATION.QUEUE) IPPROCS
Sample Output:
AMQ8450: Display queue status details. 
   QUEUE(SYSTEM.DEFAULT.INITIATION.QUEUE) 
   TYPE(QUEUE)                             CURDEPTH(0) 
   IPPROCS(1)
IPPROCS is the number of applications that have the queue open for input, or browse. This should be exactly 1.

Check the app which has the queue open is the Trigger Monitor:
DIS QS(SYSTEM.DEFAULT.INITIATION.QUEUE) TYPE(HANDLE) APPLTAG
Sample Output:
AMQ8450: Display queue status details. 
   QUEUE(SYSTEM.DEFAULT.INITIATION.QUEUE) 
   TYPE(HANDLE) 
   APPLTAG(/opt/mqm/bin/runmqtrm)
ACTION:
The trigger monitor can be started in the background as follows on UNIX:
nohup runmqtrm -m QMGR_NAME -q SYSTEM.DEFAULT.INITIATION.QUEUE >/dev/null 2>&1 &

5. The process definition must be valid
CHECK:
Display the PROCESS attribute of the triggered queue:
DIS QL(TRIGGERED_QUEUE) PROCESS
Sample Output:
AMQ8409: Display Queue details. 
   QUEUE(TRIGGERED_QUEUE)                  TYPE(QLOCAL) 
   PROCESS(TRIGGERED_PROCESS)
Ensure the process object exists, and validate the command which will be run by the trigger monitor when the trigger event occurs:
DIS PROCESS(TRIGGERED_PROCESS) APPLICID
Sample Output:
AMQ8407: Display Process details. 
   PROCESS(TRIGGERED_PROCESS)     APPLICID(/home/myuser/bin/mycmd)
ACTION:

If the PROCESS attribute is blank, or incorrect, then change it to the name of a valid process object.
If the APPLICID attribute of the process object is incorrect, then alter it to correctly match the command which should be run.
Remember that on UNIX machines commands are case-sensitive, so must be entered in single ticks when defining/altering a process object in MQSC:
DEF PROCESS(TRIGGERED_PROCESS) APPLICID('/home/myusr/bin/mycmd')

6. The trigger monitor must be able to start the application
CHECK:
If the application fails to start an application, it places the trigger message on the dead-letter queue, with a feedback code in the ‘Reason’ field.
The Application Programming Reference manual describes the possible MQFB_* feedback codes

You can use the WebSphere MQ Explorer (or MO71) to view the message:
Connect to the queue manager using the WebSphere MQ Explorer.
Browse the contents of the dead-letter queue for the queue manager.
The WMQ Explorer understands the format of the DLH header that is added to a message when it is placed on the DLQ.
Look at the ‘Reason’ field in the dead-letter header
If it is displayed in numeric form, the following link to the Constants manual should help to translate it to a MQFB_* code:

ACTION:
Investigate and resolve the problem starting the application.

7. The application must connect to the queue after it is started

CHECK:
From a WMQ administrator’s point of view, you can check whether the application is being started by the trigger monitor. Further investigation of the application’s operation would be performed by inspecting the application’s own logging/diagnostic info.

If you need to absolutely confirm that an application is being started by a trigger monitor, then the following process can be performed to restart the trigger monitor in the foreground (so you can see the output on your screen):

  1. The best way to stop a trigger monitor is to inhibit the initiation queue for get: ALTER QL(SYSTEM.DEFAULT.INITIATION.QUEUE) GET(DISABLED)
  2. You can then immediately un-inhibit get on the queue:                                    ALTER QL(SYSTEM.DEFAULT.INITIATION.QUEUE) GET(ENABLED)
  3. You can now run the trigger monitor as a foreground process, so you can monitor the output:runmqtrm -m QMGR_NAME -q SYSTEM.DEFAULT.INITIATION.QUEUE
  4. You will now need to open a new terminal (telnet/ssh session)
  5. Disable and re-enable triggering on the queue to see the output from the trigger monitor when a trigger message is processed:                                                 ALTER QL(TRIGGERED_QUEUE) NOTRIGGER                                                   ALTER QL(TRIGGERED_QUEUE) TRIGGER

2 comments: