2
votes

We have some code to send messages to a queue. It's using the amqmdnet dll version 8.0.0.6.

The queue manager (Queuemanager) is instantiated once at the start of the application and used throughout. As messages are sent, a queue object is created and then closed. Should we create a queue object for each message or is it better to use just one instance? We are writing messages only, no reads.

Here's some code:

 public QueueResult Enqueue(string message)
        {
            QueueResult result;
            using (var queue = _queueManager.AccessQueue(_queueName, MQC.MQOO_OUTPUT + MQC.MQOO_INPUT_SHARED + MQC.MQOO_FAIL_IF_QUIESCING))
            {
                var mqMessage = new MQMessage
                {
                    Format = "MQSTR",
                    Encoding = 546,
                    CharacterSet = 437
                };

                mqMessage.WriteString(message);

                var options = CreateOptions();

                queue.Put(mqMessage, options);

                result = new QueueResult
                {
                    CompletionCode = options.CompletionCode,
                    ReasonCode = options.ReasonCode
                };

                queue.Close();
            }

            return result;
        }

public IQueue AccessQueue(string queueName, int openOptions)
{
       return new Queue(mqQueueManager.AccessQueue(queueName, openOptions));
}
1
It is better to create only one instance(unless you are using a different queue) and use the same queue object for every message. - subbaraoc
Yes, your program will take a performance hit if your program opens and closes a queue for every message. It is a bad design. A better design is to connect once to the queue manager then open the queue once and do whatever processing your program needs to do. At the end, close the queue and disconnect from the queue manager. - Roger
@Roger What if this cycle is a long-running service like for example a Windows Service which is up 7 days / 24 hours? - Ozkan
@Ozkan - This is also our scenario, we have a long running web service so opening and closing a queue after every put/get is not performant at all. Was there a resolution that worked for you ? - user1554876

1 Answers

4
votes

An older IBM MQ developerWorks article has some very good recommendations in general is "The top 15 WebSphere MQ best practices". Specific to your question it states the following:

Build with performance in mind

Although MQ was built for high transaction volumes, poor architecture and application design can compromise its ability to process messages as fast and effectively as possible. To mitigate potential performance issues, here are several recommendations:

  • Keep connections and queues open if you are going to reuse them instead of repeatedly opening and closing, connecting and disconnecting.

From a IBM MQ Client standpoint each queue open and close is a round trip on the network, depending on the latency between the MQ Client and the MQ Queue manager this can cause delay on top of the processing MQ needs to do when you open and close a queue, for example checking if you have permission to open the queue and opening the underlying q file on the disk.


If you are putting persistent messages outside of a unit of work, this can cause locking contention on the queue manager with the application that is reading the messages (the reading application could be a channel agent if the queue you put to is a QREMOTE).

Putting multiple messages under the same unit of work will also increase performance, how much would depend on the underlying storage.