|
Allan Feldman, IBM TPF Development
The IBM MQSeries product is one of the fastest growing
message-oriented middleware products in the industry. Today,
MQSeries is supported by well over 17 platforms and has a growing
customer base of over 5000 customers. The ability to guarantee
delivery of messages to a diverse and heterogeneous set of systems
within and between customers with a single set of application
programming interfaces (APIs) is an attractive model for TPF
customers.
TPF MQSeries Local Queue Manager and TPF MQSeries Client
Support
On TPF program update tape (PUT) 5, IBM delivered a Message
Queue Interface (MQI) client on the TPF system. With this support,
the complete MQSeries API was enabled for TPF applications. When an
application connects to the queue manager (using the MQCONN API), a
connection is established with a remote MQSeries server (on OS/390
or AIX, for example). Each MQSeries API, in turn, is delivered to a
remote MQSeries server over LU 6.2 communication links and then
processed by the MQSeries server. The queues themselves reside on
the server, not on the TPF system. The API available to the
application is determined by the API available on the remote
server.
With our client support, the application must be prepared to
handle communication failures and system managers must be prepared
to install and maintain remote MQSeries server systems.
On TPF PUT 9, IBM delivered local queue manager support on TPF.
When an application connects to the queue manager, it can connect
to the local queue manager running on TPF. This is accomplished by
specifying the name of the local queue manager in the MQCONN API.
All subsequent MQSeries API requests will be serviced by the local
TPF queue manager. The APIs available to the local queue manager
are more restrictive than most remote servers. See the TPF
C/C++ Language Support User's Guide for specific details
about the API available.
The application can also still connect to a remote MQSeries
server using TPF MQI client support. If the application specifies
the name of a remote server queue manager in the MQCONN request,
MQCONN and all subsequent API requests will be sent to the remote
server for processing.
APIs
Nine MQSeries APIs are provided with TPF MQSeries local queue
manager support: MQCONN, MQOPEN, MQPUT, MQPUT1, MQGET, MQCLOSE,
MQDISC, MQINQ, and MQSET (MQINQ and MQSET are provided on TPF
PUT10). The options supported for each API are documented in the
TPF C/C++ Language Support User's Guide. Because the
APIs supported locally are generally more restrictive than those on
other platforms, applications that require unsupported functions
should consider using the TPF MQI client where a remote server can
satisfy the request.
Supported Queue Types
The TPF local queue manager supports three different queue
types, which are defined using the ZMQSC DEFINE Qx...... functional
message. These queue types are:
- Local
- Remote
- Alias (available with TPF PUT 10).
There are two types of local queues: normal and
transmission (xmitq). Normal local queues physically reside in
the TPF system and messages on local queues are retrieved (MQGET)
by applications. Applications can put (MQPUT) messages to local
queues for processing by a TPF application. Transmission queues
contain messages that are destined for a remote system. In fact,
the transmission queue is also physically located in TPF, but
applications do not normally get and put messages directly to them.
When an application puts a message to a remote queue, the TPF queue
manager, in turn, figures out on which transmission queue to put
the message. At some point, the channel associated with that
transmission queue takes the messages from that queue and sends
them to the remote system.
With alias queues, the system administrator can define an alias
queue that is opened by an application. However, unknown to the
application, the queue that is actually opened is some other
(target of the alias queue) local queue or local definition of a
remote queue. In this way, the administrator manages the queues
that are processed by applications. The application code never has
to change to satisfy changes in queue names.
Empty Queue Trigger User Exit
TPF does not support the normal set of event and trigger queues
provided in other MQSeries platforms. We do, however, provide a
user exit that is invoked when an MQGET request is attempted from
an empty queue that subsequently has a message put on to it. The
trigger is not set unless an application attempts to read (MQGET) a
message from the queue when it is empty. When the queue becomes
nonempty, the user exit is invoked with a trigger message on
data level 0 of the entry control block (ECB) that indicates which
queue was triggered. The user exit can interpret this data and pass
control to the appropriate application for processing the
message.
Message Routing
TPF supports several different methodologies when resolving
remote queue names:
Local Definition of Remote Queues
To remove the burden from the application of determining the
queue manager and queue to receive its message, the MQSeries
administrator can define a local definition of a remote queue that
specifies the actual destination queue manager and destination
queue name. The application opens a local name for the queue, and
the TPF queue manager will substitute the specified queue manager
and queue name and put the message on the specified transmission
queue. To define a local definition of a remote queue, use the
ZMQSC DEF QR- functional message and specify RQMNAME and RNAME and
XMITQ.
So if the administrator had defined:
ZMQSC DEF QR-RQ1 RQMNAME-QMGR1 RNAME-Q1 XMITQ-XQ1
and the application issues an MQOPEN for RQ1, the message will
be put on transmission queue XQ1 with a destination queue manager
of QMGR1 and queue Q1 specified in the transmission queue
header.
Queue Manager Aliasing
TPF also supports queue manager aliasing. Here, the name of the
remote queue is known, but not the name of the remote queue
manager. When the application opens a queue specifying a queue
manager, the TPF system will look up the name of the queue manager
and substitute the queue manager specified. Queue manager aliasing
is accomplished by leaving the QNAME field blank in the ZMQSC DEF
QR functional message.
So if the administrator had defined:
ZMQSC DEF QR-RQMGR RQMNAME-RQMGR2 XMITQ-XQ1
and the application issues an MQOPEN with a queue manager name
of RQMGR and queue name of Q1, the TPF system will put the message
on transmission queue XQ1 with a destination queue manager of
RQMGR2 and a destination queue of Q1 specified in the transmission
queue header.
Queue Manager Name As Transmission Queue Name
In addition to a local definition of remote queues and queue
manager aliasing, the system administrator can send a message to an
adjacent queue manager if the name of the queue manager opened by
the application is the same as a transmission queue.
So if the administrator had defined transmission queue:
ZMQSC DEF QL-QMGR1 USAGE-XMITQ
and the application opens a queue with a queue manager name of
QMGR1 and a queue name of Q1, the TPF system will put the message
on transmission queue QMGR1 and send the message to queue manager
QMGR1.
Middle Hop Routing
Messages received by TPF MQSeries local queue manager channels
may not be destined for the TPF queue manager. The TPF receiver
channel will invoke the local TPF queue manager to resolve the name
of the destination queue manager and queue name for each message it
receives. The queue manager and queue name are resolved according
to the rules previously stated and the message is put on the
appropriate transmission queue.
Message Types
Persistent and nonpersistent messages are supported.
Applications specify the message type in the message descriptor
(MQMD). However, the TPF implementation is slightly different from
other platforms when it comes to transmitting and receiving
nonpersistent messages over fast channels. See the description of
fast and normal channels that follows.
Channels
The TPF MQSeries local queue manager supports two channel types,
which connect to remote MQSeries systems:
- A sender (SDR) channel, which must connect only to a remote
receiver channel
- A receiver (RCVR) channel, which accepts connection requests
only from remote sender channels.
Receiver channels make use of the latest TPF Internet daemon
(INETD). When a remote sender channel first connects to the TPF
system over Transmission Control Protocol/Internet Protocol
(TCP/IP), it sends a connection request to port 1414, the standard
MQSeries port. System administrators must set up an INETD listener
on that port that, once the connection request is received, passes
control to the TPF MQSeries receiver channel session initiation
program (CMQL). The TCP/IP model used is
activate_on_receipt, which means that a TPF entry control
block (ECB) to process the session initiation request is only
created when the connection request is received. To set up the
INETD listener for MQSeries, you must add an MQSeries server using
the following functional message:
ZINETD ADD S-MQS P-TCPIP MODEL-AOR PORT-1414 PGM-CMQL AORL-8
This is required before establishing a connection between remote
sender channels and TPF receiver channels. It is possible to change
the TCP/IP port used for these connections. If you establish an
INETD listener on a different port for the MQSeries server, you
need to specify the same port in the CONNAME parameter when
defining the sender channel on the remote MQSeries system.
Two channel "speeds" are supported for both sender and receiver
channels: normal and fast.
When sending persistent messages over normal speed sender
channels, the messages are included in batches and receipt
confirmation is required before the messages are deleted from our
transmission queue. Persistent messages are never sent over fast
channels. This is a restriction that is not found on other
platforms.
When sending nonpersistent messages over fast channels, the
messages are immediately sent over the channel. They are not
included in batches and receipt confirmation is not required.
When receiving both persistent and nonpersistent messages over
normal receiver channels, the messages are processed as part of a
batch and receipt confirmation is sent for the entire batch of
messages. The messages are filed using TPF collection support
(TPFCS). Once the confirmation is sent, the messages appear on
local TPF MQSeries queues or are put on transmission queues
destined for another queue manager if the TPF queue manager is not
the target queue manager. The nonpersistent messages have an
indicator in the message descriptor saying that it is
nonpersistent. Applications must get messages from the local queues
using the MQGET function.
When receiving nonpersistent messages over a fast receiver
channel, the message is not filed and, although it is considered
part of a batch of messages, the message is assumed to be destined
for a traditional non-MQSeries application. To achieve significant
performance throughput for these messages, they are given directly
to TPF applications using the TPF-unique MQSeries ROUTC Bridge
function. The messages never appear on a queue.
MQSeries ROUTC Bridge
TPF local queue manager support includes a TPF-unique mechanism
for passing nonpersistent messages received over fast channels
directly to traditional TPF applications. In this way, TPF
customers can take advantage of MQSeries-oriented networks for
delivering older traditional, high-speed TPF-style
messages to TPF applications.
The MQSeries message is converted into TPF AM0SG format and
given to TPF message router program COA4 for routing the message to
an application. A user exit is provided that gives customers the
opportunity to assign a line number, interchange address, and
terminal address (LNIATA) to the message before giving it to the
application. In addition, the terminal address table (WGTA) for
that LNIATA is marked with an MQSeries indicator so when the
application responds to the message using the ROUTC bridge, the
message is intercepted and converted back to an MQSeries message
format.
Swinging Transmission Queues
The TPF local queue manager provides a unique feature that
redirects messages originally destined for a transmission queue to
an alternate transmission queue. If, for example, a channel is hung
or the remote receiver channel is down, messages can be moved to a
transmission queue that has an active channel. All of the messages
that were previously on the original transmission queue are moved
to the new transmission queue, and all new messages put to the
original transmission queue are actually added to the new
transmission queue. The ZMQSC SWQ functional message is used to
perform this function.
Monitoring Transmission Queue Depth
The TPF system provides a transmission queue depth monitor. When
the queue depth on a transmission queue, which is set by an
administrator, is reached (QDEPTHHI on ZMQSC DEF QL-xxxx
USAGE-XMITQ or ZMQSC DEF MQP), a warning message will be sent to
the operator console. This could mean that the transmission queue
is hung and may need operator intervention. The warning message is
sent to the console every xx seconds until the queue goes
below the QDEPTHHI value (where xx is the interval that is
determined by the administrator via the QDT keyword on the ZMQSC
DEF MQP functional message).
Debugging TPF MQSeries
Because the TPF MQSeries implementation uses TPFCS for its
database, there are several named collections that you can browse
using the TPFCS browser. You can display the named collections
using the ZBROW NAME DISPLAY ALL functional message. Don't forget
to set the browser qualifier to MQSeries data store
MQSCxxxx, where xxxx is the subsystem name (for
example, MQSCBSS).
Trace
Included in TPF MQSeries support is communications and function
trace. Communications trace was provided on PUT 9. Function trace
is being added for PUT 10.
With communications trace, the data sent and received over
channels is included in a trace block attached to the channel
definition. Much of the data will not be formatted because the
contents of the message flows are considered proprietary and
confidential.
With function trace, you can trace function calls in the three
different areas of MQSeries:
- Administrative (ZMQSC functional messages)
- Queue manager
- Communications.
Each function that is called and returned creates an entry in a
trace block that is attached to the ECB. The trace data can be used
for problem determination. You can function trace individual
channels or queues, or all channels or all queues.
Trace data can be sent to either the console, the RTA tape, both
the RTA tape and console, or neither. It is strongly recommended
that sending trace data to the console be restricted to test system
environments only.
Packaging
Most of MQSeries is contained in a dynamic link library (DLL)
called CMQS. CMQS contains the entry points for the MQSeries APIs
as well as the entry points for the MQSeries dynamic link modules
(DLMs): CMQL, CMQR, CUIU, CUIE, CUIF, CUIK, CUIM, CUIR, CUIX, and
CUSC. The C linkage into the CMQS entry points requires a
side-deck, which is produced when CMQS is link-edited. The
side-deck is then imported into any DLM that requires those entry
points, including the MQSeries DLMs. In addition, any customer
application that issues an MQSeries API must also import the CMQS
side-deck.
Header file CMQC.H contains the prototypes for the function
calls to the MQSeries APIs. Any customer application that is
currently using MQI client support links into the MQI client C
library called CMQI. With delivery of local queue manager support
on PUT 9, the prototypes defined in CMQC.H for the MQSeries APIs
have changed. Each function name has been redefined with a prefix
of zst. Therefore, MQCONN is defined as zstMQCONN and MQOPEN is now
zstMQOPEN. While applications still code MQCONN and MQOPEN, they
are turned into zstMQCONN and zstMQOPEN at compile time. The
linkage to zstMQCONN (because it is included in the CMQS side-deck,
not in the CMQI transfer vector) goes into CMQS, which now
determines whether MQCONN is for the local queue manager or for a
client queue manager. If the name of the queue manager in MQCONN is
the same as the name of the local TPF queue manager, CMQS will then
process the local request. If the name of the queue manager in
MQCONN is not the name of the local queue manager, CMQS will then
pass control to CMQI to process a client request.
Because there is only one copy of CMQC.H for both client and
local queue manager MQSeries applications, any existing MQI client
application should be recompiled to pick up the new linkage. In
addition, some of the fields in CMQC.H have changed. Of course, if
you do not recompile your client application, the linkage into CMQI
will not change and the code should work as before, but this is not
recommended.
The CMQS DLL is quite large and contains several object code
only (OCO) modules. Customers must compile the non-OCO MQSeries
modules using a C++ compiler and link-edit them using the CMQSBS
build script. The OCO modules shipped by IBM have been compiled
using the OS/390 Version 2 Release 4 (2.4) C++ compiler. It is
strongly recommended that customers compile the non-OCO modules
using the C++ compiler and linkage editor shipped with OS/390 2.4.
Attempting to link-edit some modules compiled with an older version
of the compiler and linkage editor and link-editing them with the
OCO modules compiled with OS/390 2.4 may produce linkage editor
errors.
Important: When compiling, use the OPTIMIZATION (0)
compiler option. However, the known OS/390 2.4 C++ compiler bug
with optimization level 1 has since been fixed by APAR PQ24612.
Offline program CMQMPP is used to postprocess trace data from an
RTA tape. CMQMPP is also shipped as OCO, but was compiled using the
C compiler (not C++) and does not require prelinking because it was
compiled with the NORENT and NOLONGNAME options. Therefore, the
linkage editor job control language (JCL) produced by the system
initialization program (SIP) calls CEEWL, which does not invoke the
prelinker. The original JCL produced by SIP (PUT 9) called EDCL,
which is a PROC that is only available on older versions of OS/390.
With PUT 10, the GENSIP macro was changed to produce JCL that calls
CEEWL.
What Is New on TPF PUT 10?
Alias Queue
Applications can specify an alias queue name when opening
queues. The real queue name is not known to the application. The
real queue can be a local queue or a local definition of a remote
queue. A new functional message (ZMQSC DEF QA-) is available to the
MQSeries administrator for defining alias queues.
Function Trace
Previously, TPF local queue manager support included channel
trace where data sent and received over channels was dumped to an
RTA tape and postprocessed in an offline environment. With PUT 10,
a function trace is available that shows the logic flow of function
entry and exit for channels, queue manager functions, and
administrative functions. Trace output can be sent to the RTA tape,
to the console, to both, or to neither. Of course, sending trace
output to a console in a production system is dangerous and should
be avoided.
MQSET/MQINQ
Two new MQSeries APIs are now supported in the local queue
manager. These APIs let applications inquire about queue and queue
manager attributes or set queue attributes.
Disable Receiver Channel
Receiver channels on the TPF local queue manager can be disabled
by issuing a ZMQSC STOP CHL functional message. This function
prevents remote sender channels, which may be looping or generating
erroneous messages, from establishing a connection with the TPF
MQSeries system.
Tips for Administering Your Local Queue Manager
The administrative functions in the TPF implementation of an
MQSeries local queue manager are similar to, but not exactly the
same as, other platforms. Some of the functions are unique because
of the loosely coupled nature of TPF systems, while other
differences result from the fact that TPF maintains some of the
MQSeries object definitions in system heap for performance.
Defining the MQSeries Profile
When you define the MQSeries profile (ZMQSC DEF MQP...) for the
first time, you must specify how many queues and channels you need
via the MAXQUE and MAXMCA parameters. Because the queue definitions
and channel definitions are loaded into system heap memory for
performance, these parameters determine how much system heap will
be needed for these definitions. So if you set MAXMCA to 20, the
channel definition table will contain 20 entries. If you decide you
need more, you can always alter the MQSeries profile (ZMQSC ALT
MQP...), but you will need to stop and start the queue manager so
the system can reallocate the system heap for the new tables.
Also, when you define the MQSeries profile, the TPF system
automatically provides a system queue called dead-letter
queue. This is the only default queue provided. Other platforms
provide several other default queues. Any message that arrives at
the TPF system whose destination queue name cannot be resolved is
put on the dead-letter queue. All customers are expected to create
a monitor for the dead-letter queue that determines what to do with
messages that arrive there.
Common-Yes for Local Queues
In a loosely coupled environment, normal local queues can be
shared between processors or they can be processor unique. When you
define a local queue (ZMQSC DEF QL-xxx USAGE-NORMAL), you
can specify that you want all processors to see the queue by
specifying COMMON-YES. When COMMON-YES is coded, a single TPFCS
persistent identifier (PID) (yes, we used collection support for
our queues!) is then used for the queue that all of the processors
can see. Messages put on the queue from processor A can be
retrieved from processor B. When COMMON-NO is coded, each processor
in the complex will be allocated a different TPFCS PID and each
processor will, in effect, have its own copy of the queue. Messages
that are put on the queue from processor A will only be visible to
processor A.
Note also that if you define a COMMON-NO queue, the queue
definition will exist on all processors. So even though you define
a queue on processor A, the queue name will exist on processor B;
it will just have its own copy of the queue.
Obviously, if you can live with the I/O contention for a
shared queue, that is the way to go. If you cannot, you should
then specify COMMON-NO. Of course, either way, the application may
need to be aware of whether the queue is available on all
processors.
You should also be aware that once you have specified whether
the queue is shared or not, you cannot alter this attribute. To
change it, you will need to delete the queue and redefine it with
the new attribute.
Finally, transmission queues are all processor unique because
they are all associated with channels that are also, by definition,
processor unique. Remote queues are really virtual and actually get
resolved to physical transmission queues.
CPU Parameter for Channel Definitions
Channels, by nature, are processor unique. Each processor
establishes an MQSeries channel connection to an adjacent MQSeries
system. As a matter of convenience, the TPF system provides a CPU
parameter for the functional messages that define and alter channel
definitions. In this way, an operator on processor A can define or
alter channels on processor B even while processor B is down.
Altering Definitions
Because our channel and queue definitions reside in memory, and
because we do not want to lock the tables for each access, changes
to these definitions do not always occur immediately. For changes
to channel definitions, the channel must be stopped and restarted.
For queue definition changes and queue manager definition changes,
the queue manager must be stopped and restarted.
|