ince the release of the first version of MSMQ in December of 1997, it has provided the plumbing required by many enterprise applications. Before MSMQ, developers implemented tools with similar functionality using input/output directories with files, SQL Server tables, DCOM, TCP/IP sockets, etc. The major shortcoming in all these approaches was the complexity of delivering a robust systemperformance took a back seat. MSMQ's release provided the standardized messaging platform that many projects neededa great head-start for developers building enterprise solutions.
Unfortunately, MSMQ fell short in delivering the level of performance and robustness required by many projects. As message volume grew, and demand for 'always on' reliability increased, many found MSMQ falling short. However, after many troubleshooting sessions involving Microsoft engineers, important ways of increasing both the performance and robustness of MSMQ emerged. In this article, I've listed these options, arranged as tips that significantly impact messaging performance and tips that improve reliability using MSMQ.
Increasing MSMQ Performance
If you're not already intimately familiar with MSMQ, I encourage you to review the documentation for MSMQ versions 2.0 and 3.0. You can find documentation links in the Related Resources section of this article that outline all the major features. The tips you'll find here don't rehash the documentation; instead, they provide advice widely applicable to most MSMQ installations.
Tip 1: Use Recoverable Messages Only When Necessary
By default, MSMQ processes messages as quickly as possible, at the risk of possibly losing the messages if the machine is rebooted or if the MSMQ service is restarted. MSMQ stores all the messages in memory to increase performance. Unless your application is designed to survive the loss of messages, you really don't have many optionsyou probably need to make your messages recoverable.
This recoverability comes at a cost. In my unofficial tests, I found that messages took about 3-6 times longer to send when the messages were configured as recoverable. The real difference will depend heavily on the disks you are using on the receiving machine (and on the sending machine if the sender is disconnected from the receiver), but you get the general idea. Below is a listing of the change necessary to configure a message to be recoverable.
Dim msmqMessage As System.Messaging.Message
msmqMessage = New System.Messaging.Message("Hello World")
msmqMessage.Recoverable = True 'default is False
The code required to retrieve recoverable messages is the same as that required to retrieve non-recoverable messages. The receiving application does not treat the messages differently. See the code sample below for an example of retrieving messages.
Dim msmqQueue As System.Messaging.MessageQueue
Dim msmqMessage As System.Messaging.Message
msmqQueue = New MessageQueue( _
msmqMessage = msmqQueue.Receive()
Recoverable messages, while they significantly decrease performance, can increase the robustness of the application considerably. If it is important that messages are not lost, then configuring for recoverable messages will help to prevent communications failures.
Tip 2: Do Not Use Journaling
|Figure 1. Enabling Journaling: Use the property window of a message queue to enable journaling.|
Journaling is a feature that allows a copy of the retrieved message to be copied into a special queue when it is retrieved by the receiving application. The journal messages are stored in a Journal queue associated with the queue the message was retrieved from. This feature is useful mainly for debugging and auditing, and should not be used on production systems except for brief periods. While the performance overhead of retrieving messages from a queue that is configured for Journaling is only about 20% more than retrieving messages without Journaling, the real cost is unexpected problems caused when an unchecked MSMQ service runs out of memory or the machine is out of disk space. There is no measurable difference in sending messages to a queue configured for Journaling; the overhead is incurred when retrieving messages. You can enable journaling on a queue by opening the queue properties and clicking the Enabled checkbox in the Journaling section of the window (see Figure 1
After retrieving messages from a queue enabled for Journaling, you can view the messages in the Journal queue using the MSMQ administrative tool in Computer Management (see Figure 2
). The tool shows the messages that have been retrieved from the queue. To see the details of an individual message, double-click a message in the queue's journal. The tool lets you view the body of the message as well as details about when the message was sent and received, (see Figure 3
|Figure 2. Viewing Journaling Queue Contents: You can view the contents of a queue's journal using the MSMQ administrative tool in Computer Management.||
|Figure 3. Viewing Individual Journal Messages: The properties window for a queue journal message displays the body of the message.|