Application design and performance considerations

There are a number of ways in which poor program design can affect performance. These can be difficult to detect because the program can appear to perform well itself, but affect the performance of other tasks. Several problems specific to programs making IBM MQ calls are explained in this topic.

Here are a few ideas to help you to design efficient applications:

  • Design our application so that processing goes on in parallel with a user's thinking time:

    • Display a panel and allow the user to start typing while the application is still initializing.
    • Get the data that you need in parallel from different servers.
  • Keep connections and queues open if you are going to reuse them instead of repeatedly opening and closing, connecting, and disconnecting.
  • However, a server application that is putting only one message should use MQPUT1.
  • Queue managers are optimized for messages between 4 KB and 100 KB in size. Very large messages are inefficient; it is probably better to send 100 messages of 1 MB each than a single 100 MB message. Very small messages are also inefficient. The queue manager does the same amount of work for a single-byte message as for a 4 KB message.
  • Keep your messages within a unit of work so that they can be committed or backed out simultaneously.
  • Use the nonpersistent option for messages that do not need to be recoverable.
  • If you need to send a message to a number of target queues, consider using a distribution list.


Effect of message length

The amount of data in a message can affect the performance of the application that processes the message. To achieve the best performance from our application, send only the essential data in a message. For example, in a request to debit a bank account, the only information that might need to be passed from the client to the server application is the account number and the amount of the debit.


Effect of message persistence

Persistent messages are usually logged. Logging messages reduces the performance of your application, so use persistent messages for essential data only. If the data in a message can be discarded if the queue manager stops or fails, use a nonpersistent message.

MQPUT and MQGET operations for persistent messages will block when there is insufficient recovery log space to record the operations. Such a condition is indicated in the queue manager job log by messages CSQJ110E and CSQJ111A. Ensure monitoring processes are in place so that such conditions are managed and avoided.


Searching for a particular message

The MQGET call usually retrieves the first message from a queue. If we use the message and correlation identifiers (MsgId and CorrelId) in the message descriptor to specify a particular message, the queue manager has to search the queue until it finds that message. Using the MQGET call in this way affects the performance of our application.


Queues that contain messages of different lengths

If our application cannot use messages of a fixed length, grow and shrink the buffers dynamically to suit the typical message size. If the application issues an MQGET call that fails because the buffer is too small, the size of the message data is returned. Add code to your application so that the buffer is resized accordingly and the MQGET call is reissued.

Note: If we do not set the MaxMsgLength attribute explicitly, it defaults to 4 MB, which might be very inefficient if this is used to influence the application buffer size.


Frequency of sync points

Programs that issue very large numbers of MQPUT or MQGET calls within sync point, without committing them, can cause performance problems. Affected queues can fill up with messages that are currently inaccessible, while other tasks might be waiting to get these messages. This has implications in terms of storage, and in terms of threads that are tied up with tasks that are attempting to get messages.


Use of the MQPUT1 call

Use the MQPUT1 call only if we have a single message to put on a queue. If you want to put more than one message, use the MQOPEN call, followed by a series of MQPUT calls and a single MQCLOSE call.


Number of threads in use

For IBM MQ for Windows, an application might require a large number of threads. Each queue manager process is allocated a maximum allowable number of application threads.

Applications might use too many threads. Consider whether the application takes into account this possibility and that it takes actions either to stop or to report this type of occurrence.


Put persistent messages under syncpoint

Persistent messages should be put and got under syncpoint. This is because when getting a persistent message outside of syncpoint, if the get fails, there is no way for the application to know whether the message has been got from the queue or not, and whether, if the message has been got, then it has also been lost. When getting persistent messages under syncpoint, if anything fails, the transaction is rolled back and the persistent message is not lost because it is still on the queue. Similarly, when putting persistent messages, put them under syncpoint. Another reason for putting and getting persistent messages under syncpoint is that the persistent message code in IBM MQ is heavily optimized for syncpoint. So putting and getting persistent messages under syncpoint is faster than putting and getting persistent messages outside of syncpoint.

However, it is faster to put and get non-persistent messages outside of syncpoint because the nonpersistent code in IBM MQ is optimized for being outside of syncpoint. Putting and getting persistent messages go at disk speeds because the persistent message is persisted to disk. However, putting and getting non-persistent messages go at CPU speeds because there is no disk write involved, not even when using syncpoint.

If an application is getting messages and does not know in advance whether they are persistent or not, the GMO option MQGMO_SYNCPOINT_IF_PERSISTENT can be used.