IBM MQ

IBM MQ Recipe

  1. Test with SHARECNV(1) to potentially increase throughput per socket: https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.1.0/com.ibm.mq.mon.doc/q036143_.htm

MQ versus WAS SIB

As of Sep. 2011, performance of WebSphere MQ persistent messages is approximately twice as fast as SIBus persistent messages. There is little difference for non-persistent messages.

WebSphere MQ supports clustering of queue managers for enhanced throughput and scalability of administration. There are many examples of production clusters containing thousands of queue managers. WebSphere MQ clustering is extremely flexible, supporting selective parallelism of cluster queues, enabling you to independently tailor the number of instances of each cluster queue. SIBus messaging engines can be clustered within a WebSphere Application Server cluster for throughput and administrative scalability. However, a WebSphere Application Server cluster has a much lower scalability limit than a WebSphere MQ cluster, and if a queue is assigned to a WebSphere Application Server cluster bus member, it is partitioned across all messaging engines in the cluster -- you cannot selectively locate partitions. (http://www.ibm.com/developerworks/websphere/library/techarticles/1109_wallis/1109_wallis.html)

WAS Considerations

Listener ports are "stabilized" (no more investment from IBM) and activation specifications are the recommended approach to integrate with WMQ.

Consider various queue properties: https://www.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/tmj_wmqmp_tuned.html

For z/OS, consider this tuning: https://www.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/tprf_tunezmdb.html

If using listener ports, monitor the session pool size: https://www.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/tmb_adm15.html

For the JMS WASMQ Message Provider Resource Adapter Properties (http://www.ibm.com/developerworks/websphere/library/techarticles/1308_broadhurst/1308_broadhurst.html)

  • Max Connections. Practice is to set this to 2147483647 (maximum possible). This must be set at the same scope as the activation specification. Since activation specifications are generally set at Node scope, Max Connections should be set at Node scope too.
  • Connection Concurrency. Practice is to have this property equal 1. Note for WebSphere 8.5, the connectionConcurrency property has been set to 1 as default and made a no-op, so it is not required to explicitly set it. For WebSphere versions earlier than 8.5, this should be set at cell scope.

WAS MQ Resource Adapter

Best Practices

http://www.ibm.com/developerworks/websphere/library/techarticles/0807_hsieh/0807_hsieh.html

  • Message size and length can affect the performance of the application that processes the message, and the network time of data transmission. Send only essential data in the message.
  • Use persistent messages for critical or essential data only. Persistent messages are logged to disk and can reduce the performance of your application.
  • Retrieving messages from a queue by message or correlation identifiers will reduce application performance. It causes the queue manager to search all messages in the queue until it finds the desired message. If applications have high-performance requirements, applications should be designed to process messages sequentially.
  • The MaxMsgLength parameter stores the value for the maximum size of a message allowed on the queue. The 4 MB default can be changed to better align with your application processing needs, which will have the benefit of using system resources in the most efficient manner.
  • Ensure that messaging applications are designed to work in parallel with each other and with multiple instances of applications. The queue manager executes one service request within a queue at a given time to maintain integrity. Avoid programs that use numerous MQPUT calls in a sync point without committing them. Affected queues can fill up with messages that are currently inaccessible while other applications or tasks might be waiting to get these messages.
  • When applications have intermittent message transmission needs, use the MQPUT1 call to put only one message on the queue. For higher volume applications, where multiple messages are being put, consider an alternative to the traditional usage of an MQOPEN call followed by a series of MQPUT calls and an MQCLOSE call.
  • Keep connections and queues open if you are going to reuse them instead of repeatedly opening and closing, connecting and disconnecting.
  • The maximum number of threads an application can run on a system can affect the performance of the solution, especially on Windows.
  • Configure channels with a disconnect interval so that they can go inactive when there is no activity on the channel after a period of time. This will reduce overhead and help improve overall performance.
  • MQ performance is commonly bound by disk I/O writes. Ensure that the storage team is involved with disk layouts to ensure the fastest reliable disk writes possible.
  • When using clusters: "Adding more than two full repositories often degrades overall performance, because the cluster will need to send additional traffic and spend more time maintaining all of the repositories... [I]t is usually better to create one queue manager with 100 queues as opposed to 100 queue managers with one queue apiece."

Large message depths on your WebSphere MQ queues could cause performance issues. Storing thousands of messages on a single queue is not a best practice.

MQ Documentation

The WebSphere MQ library has links to documentation for all versions of MQ: http://www-01.ibm.com/software/integration/wmq/library/index.html

Basic MQ Display Commands

  • dspmqinst lists the MQ installations on the machine

  • dspmqver shows the MQ version and patch level

  • dspmq lists queue managers on the local machine, and the status of each one

DISPLAY QSTATUS

Documentation: https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.1.0/com.ibm.mq.ref.adm.doc/q086260_.htm

Example output:

     1 :  DISPLAY QSTATUS(MDM.MESSAGING.REQUEST) TYPE(QUEUE) ALL
AMQ8450: Display queue status details.
   QUEUE(MDM.MESSAGING.REQUEST)            TYPE(QUEUE)
   CURDEPTH(0)                             IPPROCS(177)
   LGETDATE(2020-04-22)                    LGETTIME(06.47.13)
   LPUTDATE(2020-04-22)                    LPUTTIME(06.47.13)
   MEDIALOG( )                             MONQ(HIGH)
   MSGAGE(0)                               OPPROCS(5)
   QTIME(2323, 2042)                       UNCOM(NO)

Key outputs:

  • CURDEPTH: The current depth of the queue, that is, the number of messages on the queue, including both committed messages and uncommitted messages.

  • LGETDATE/LGETTIME: The date [and time] on which the last message was retrieved from the queue since the queue manager started. A message being browsed does not count as a message being retrieved.

  • LPUTDATE/LPUTTIME: The date [and time] on which the last message was put to the queue since the queue manager started.

  • MSGAGE: Age, in seconds, of the oldest message on the queue. The maximum displayable value is 999999999

  • IPPROCS: Number of concurrent getters (e.g. WAS MDBs), although the actual number is potentially up to IPPROCS * SHARECNV. The size of the Server Session Pool for the Activation Specification determines how many messages are processed concurrently by message-driven beans that use this activation specification. This defaults to 10 and you can configure this via "Maximum Server Sessions' under the 'Advanced Properties' tab for the Activation Spec in the Admin Console.

  • OPPROCS: Number of concurrent putters.

  • QTIME: Interval, in microseconds, between messages being put on the queue and then being destructively read. The interval is measured from the time that the message is placed on the queue until it is destructively retrieved by an application and, therefore, includes any interval caused by a delay in committing by the putting application. Two values are displayed and these are recalculated only when messages are processed: A value based on the last few messages processed and A value based on a larger sample of the recently processed messages. These values depend on the configuration and behavior of your system, as well as the levels of activity within it, and serve as an indicator that your system is performing normally. A significant variation in these values might indicate a problem with your system.

  • UNCOM: Indicates whether there are any uncommitted changes (puts and gets) pending for the queue.

Extracting periodic file output to a CSV:

#!/bin/awk -f
BEGIN { print "LGETDATE,LGETTIME,CURDEPTH,IPPROCS,MSGAGE,OPPROCS,QTIME1,QTIME2,UNCOM"; }
/CURDEPTH/ {
  curdepth=$1;
  curdepth=substr(curdepth, 10);
  gsub(/\)/, "", curdepth);
  curdepth=getASCII(curdepth);
  ipprocs=substr($2, 9);
  gsub(/\)/, "", ipprocs);
  ipprocs=getASCII(ipprocs);
}
/LGETDATE/ {
  lgetdate=substr($1, 10, 10);
  lgetdate=getASCII(lgetdate);
  lgettime=substr($2, 10, 8);
  gsub(/\./, ":", lgettime);
  lgettime=getASCII(lgettime);
}
/LPUTDATE/ {
  lputdate=substr($1, 10, 10);
  lputdate=getASCII(lputdate);
  lputtime=substr($2, 10, 8);
  gsub(/\./, ":", lputtime);
  lputtime=getASCII(lputtime);
}
/MSGAGE/ {
  msgage=substr($1, 8);
  gsub(/\)/, "", msgage);
  msgage=getASCII(msgage);
  opprocs=substr($2, 9);
  gsub(/\)/, "", opprocs);
  opprocs=getASCII(opprocs);
}
/QTIME/ {
  qtime1=substr($1, 7);
  gsub(/,/, "", qtime1);
  qtime1=getASCII(qtime1);
  qtime2=$2;
  gsub(/\)/, "", qtime2);
  qtime2=getASCII(qtime2);
  uncom=substr($3, 7);
  gsub(/\)/, "", uncom);
  uncom=getASCII(uncom);
  printf("%s,%s,%s,%s,%s,%s,%s,%s,%s\n", lgetdate, lgettime, curdepth, ipprocs, msgage, opprocs, qtime1, qtime2, uncom);
}
function getASCII(str) {
  gsub(/[^\40-\176]/, "", str);
  return str;
}

If you want to know which PIDs are reading/writing messages to a particular queue, use the following command:

DISPLAY QSTATUS(QName) TYPE(HANDLE) ALL

Then look for the PID and grep for that PID to know which application is using that queue. You need to look for the APPLTYPE(USER) and not the APPLTYPE(SYSTEM).

Performance differences across MQ versions

Official WebSphere MQ Performance Reports are available via the MQ SupportPac site here.

Windows and UNIX Performance Tuning

Configuring and tuning WebSphere MQ for performance on Windows and UNIX: http://www.ibm.com/developerworks/websphere/library/techarticles/0712_dunn/0712_dunn.html

  • Queue manager log configuration (applicable only when using persistent messages)
  • More tips related to persistent messages:
    • "When processing persistent messages it is recommended to run many instances of the application concurrently in order to optimise the efficiency of the queue manager log."
    • "When processing persistent messages in an application you should ensure that all MQPUT and MQGET activity takes place within a unit of work, or syncpoint as it is sometime referred to, for efficiency purposes."
  • Fastpath channels, fastpath listeners
  • Queue buffer sizes

WMQ JMS Client

https://www.ibm.com/developerworks/mydeveloperworks/blogs/messaging/entry/programming_a_websphere_mq_jms_client_for_performance7

If possible:

  • Use non-persistent messages
  • Use bindings mode
  • Use correlation ID when using selectors
  • Use the async put feature
  • Use read-ahead when you can, with non-persistent messages
  • Use conversation sharing / multiplexed sockets
  • Use non-transacted sessions

Resources

MQ Performance Reports: http://www-01.ibm.com/support/docview.wss?uid=swg27007150

  1. MP01: WebSphere MQ - Tuning Queue limits
  2. MP06: WebSphere MQ with JMS: Get the Best from WMQ and MB Pub/Sub Processing
  3. MP7A: WebSphere MQ for Windows V5.3 - Performance tuning for large clusters
  4. There is also a performance monitoring Support Pac, MP08

MQ v7 JMS performance evaluations (vastly improved in V7): http://www-01.ibm.com/support/docview.wss?uid=swg24022778