Вы находитесь на странице: 1из 6

A Day In the Life of an MQSeries Message

First of Two Articles

program one that is connected to a remote queue manager and receiving a reply at the local queue manager. Scenario

Figure 1. Message Life Cycle Assume Program A wants to send a message via MQSeries to Program B. Program A generates the message on local queue manager QM1, which resides on HOST1, and sends the message to remote queue manager QM2, which resides on HOST2. Program B retrieves the message from QM2 and sends a reply back to Program A, concluding the message life cycle. Whats a Message?

Figure 2. The Components of an MQSeries Message An MQSeries message consists of a header and application data. The message header contains information about the attributes of a particular message and accompanies the message between application programs. Within the message header is a message descriptor, which contains such information as message type, persistence, priority, accounting information, reply to queue and reply to queue manager. The Application Program Assume the following statements are coded in Program A:

MQCONN HConn, QMR MQOPEN HConn, Hobj, ObjDesc MQPUT1 HConn, ObjDescP, MsgDesc, Buffer

QMR ObjDesc

= "QM1" = "SYSTEM.REPLY.TO.MODEL"

ObjDescP = "QM2.LOCAL.QUE2" MsgDesc = "QM1.Dynamic.R2Q.*" Buffer = "Message1" How Is a Message Born? A message is born when a program "puts" it to an MQSeries queue. Applications use the MQPUT API call to place messages on a message queue. Upon issuing the MQPUT API call, the message is copied from a storage area within the application program to the MQSeries message queue. An MQPUT API call must be preceded by an MQCONN and an MQOPEN API call for it to complete successfully. The application program begins by requesting connection to a specific queue manager using the MQCONN macro. The first parameter on the macro indicates the name of the queue manager to which the application program will connect. MQSeries returns a connection handle back to the application program in the storage area pointed to by the second parameter. The connection handle is used to identify the application program to MQSeries on subsequent MQSeries API calls. The handle is valid until the application disconnects from the queue manager with an MQDISC API request. For Program A to send a message to a second program, which in turn sends a reply, both the target queue and the reply queue must be defined. However, since the reply queue is often transient in nature, it is desirable to define this queue at message-generation time. The MQOPEN API request can be used to define a reply to queue. Generating a Dynamic Reply Queue The MQOPEN request typically opens a message queue. The connection handle is required as well as three other parameters: object descriptor, object handle and open options. The object descriptor (OD) identifies the queue name to be opened. The object handle is returned by the queue manager and identifies the queue manager in subsequent requests. The open options specify how the queue is opened: read, write, etc.

We will be reading the reply to queue. A special form of the MQOPEN allows the application to define a reply queue dynamically when a model queue name is specified in the OD queue name field. A model queue is not a real queue but a set of pre-defined attributes that are used as a template when generating a dynamic queue with the MQOPEN call. This special form of MQOPEN is the technique used in this example to create and open the reply to queue in read mode. Next, an MQPUT1 call sends the message to QM2.LOCAL.QUE2. The MQPUT1 is a quick way to send one message to a queue. When the MQPUT1 is issued, the queue manager calls internal

routines to perform an MQOPEN, an MQPUT and an MQCLOSE on your behalf. Do not confuse the MQOPEN performed in the MQPUT1 call with the previous MQOPEN. There is no relationship between the MQOPEN issued to create the dynamic queue and the MQPUT1 issued against the remote queue. The MQPUT1 API call requires a connection handle, an object descriptor, put message options, a buffer and a buffer length. As with the MQOPEN, the object descriptor is used to indicate the target queue. The put message options are used to specify the reply queue name. This field is made available to Program B, where it is used to determine the name of the reply queue. The buffer and buffer length indicate the location and length of the message being sent to QM2.LOCAL.QUE2 on QM2. Once the MQPUT1 is issued, Program A issues an MQGET on the reply to queue, waiting on the response to arrive from Program B. Definitions Required on Queue Manager QM1 Assume the MQSeries definitions are found on QM1 as illustrated in Figure 3, below. Figure 3. MQSeries Definitions

After the QM1 queue manager receives control from the MQPUT1, a process known as name resolution is performed. Name resolution locates the target queue name specified in the object descriptor. In its simplest form, name resolution results in one of three outcomes: the target queue is either located on QM1, located on another queue manager or cannot be found. A remote queue definition is specified on QM1 that indicates the location of QM2.LOCAL.QUE2 is QM2. The queue manager determines the route to QM2 by the XMITQ keyword on the QREMOTE definition. The QM2 value is a signal to locate a transmission queue with the same name. The message is queued to the transmission queue after a transmission header is prefixed to the front of the message.

Is This Message for Me? If a message is destined for a local queue, addressing information is not necessary because the destination queue is the address. However, if the message destination is a remote queue, a transmission header is added by the queue manager prior to placement on a transmission queue.

This header contains the destination queue and queue manager for use by the receiving systems Message Channel Agent (MCA). An MCA is an MQSeries process that reads the transmission queue and issues the TCP/IP API calls to send and receive the message traffic. The receiving channel removes this header after receipt and before the message is put on the destination queue. A transmission queue is nothing more than a local queue with USAGE=XMITQ specified on the definition. We will see in a moment how this ties a specific channel with a transmission queue. Assume the following channel definition exists on QM1: CHANNEL (QM1 TO QM2) CHLTYPE(SDR) CONNAME(HOST2) TRPTYPE(TCP) XMITQ(QM2) QM1 is using a sender-receiver channel pair to communicate with QM2. There are several keywords associated with channel definitions, but you can allow most to default. The CHANNEL, CHLTYPE, CONNAME, TTRPTYPE and XMITQ keywords are all required for sender channels. The CHANNEL keyword specifies the name of the channel and must match the receiver channel name on QM2. The CHLTYPE=SDR indicates this is the sender side of a sender-receiver channel pair. TRPTYPE=TCP indicates TCP/IP is used as the communication access method. The XMITQ keyword specifies the name of the transmission queue for this channel. This keyword indicates to the MCA which queue to obtain the message for transmission to QM2. The CONNAME keyword indicates the host name where QM2 runs. Alternatively, the IP address can be specified in this field. If the host name is specified, then the Domain Name Server (DNS) must be able to resolve the IP address. DNS address resolution is beyond the scope of this discussion. With the MQSeries channel definitions are underlying network definitions that must be in place for messages to travel between hosts.

Living the Good Life on QM2 Since QM1 is using a sender-receiver channel pair, for this channel to start, the following complementary receiver channel definition must exist on QM2: CHANNEL(QM1 TO QM2) CHLTYPE(RCVR) TRPTYPE(TCP) The receiver channel is defined on the QM2 side of the connection. The CHLTYPE keyword must be defined as RCVR and the TRPTYPE must specify TCP. The CHANNEL keyword must be the same as the sender definition on QM1.

An MQSeries START CHANNEL command must be issued on QM1 to establish the connection. This command is issued using the CSQUTIL batch program on MVS or the RUNMQSC command under Unix, NT or OS/2. A listener program must also be started on HOST2 to detect incoming network requests from QM1 and to start the receiver channel. Listener programs are platform specific, but under Windows NT, the listener program would be started with the command RUNMQLSR -t tcp -m QM2 -p 1414. (Where "t" is the transmission protocol, "m" is the queue manager name and "p" is the port number for TCP/IP; the default of 1414 is used.) A listener program must also be started from the second sender-receiver channel QM2.TO.QM1 for the reply message to be sent back to Program A. Once the channel is active, the message channel agent begins sending the message across the channel connection. The MCA on QM2 receives the message and performs name resolution to determine if the target queue is local or remote. Assume the following definition exists on QM2: Define QLOCAL(QM2.LOCAL.QUE2) USAGE(NORMAL) In this situation, the MCA locates the QLOCAL definition for QM2.LOCAL.QUE2 and places the message on that queue. Program B obtains the message by issuing an MQGET for QM2.LOCAL.QUE2. Defining the QM2.LOCAL.QUE2 as a trigger queue can start the program when the message arrives. An alternative technique is to have the program issue the MQGET with the MQGMO_WAIT message option, which would cause the program to wait until the message arrives. Return Trip After processing the message, Program B obtains the reply queue name from its message descriptor. A reply is sent back to Program A with an MQPUT1 macro. QM2 performs name resolution and determines that the message header contains a queue manager name different from the local queue manager. Since QM2 now has determined that the reply message is destined for a remote queue, the queue manager looks for a transmission queue. The QM2 queue manager locates a transmission queue named QM2 and puts the reply on that queue. The MCA for the QM2.TO.QM1 sender channel reads the message and sends it across to the MCA on QM1. The MCA for the QM2.TO.QM1 receiver channel reads the transmission header and removes this header before it queues the message to the reply queue. The MQGET API call, which Program A issued in the beginning, is now satisfied. The message is logged and then deleted from the reply queue, completing the life cycle.

Вам также может понравиться