Infosys Microsoft Alliance and Solutions blog

« Working with MSMQ Journal Queues | Main | Required Field Validation in WPF »

Are Remote MSMQ Queues Reliable?

I have played around a bit with MSMQ private queues and documented some of my findings earlier. In my first blog on this topic, I had captured how the naming of the queue is critical to connect to the right queue.

If it was local private queue, you could use - ".\\private$\\queuename"

and if it was remote private queue, you use - "FormatName:Direct=OS:machinename\\private$\\queuename"

In my second blog, I mentioned about how to receive messages from remote private queues. The key to receiving message (apart from the correct queue format name) was to have an appropriate formatter so that the messages from the queue can be read properly.

What I do find strange is that attaching a formatter isn't necessary when sending messages. If a default formatting is plugged in automatically in that case, why can't one be plugged-in in case of receiving messages. One reason, I can think of is probably the outgoing formatting is decided based on the message type being sent out. While in case of reading, you don't know what is being read and can be a security issue as well if you try to read from the queue without really knowing what to expect.

Finally, in my third blog, I discussed about how to configure and use journal queues.

What has intrigued me is some of the comments that people have raised on these blog and my own experiment results. I document them there.

When working with remote private MSMQ queues, keep in mind that they aren't 100% reliable. Well the queues as such are, but the way the .net APIs function, they appear to be not. Very simply, an application can't easily find out if a particular private queue exists on a remote machine or not. You could use the static method MessageQueue.GetPrivateQueuesByMachine() and pass the remote machine name and get the list of queues on it, but when sending a message, if for some reason, the queue has been deleted the message will still be sent from the application and it will be lost.

MessageQueue.GetPrivateQueuesByMachine() returns a MessageQueue collection and you can access the FormatName property of individual queues in this collection, to get the correct format name for the remote private queues. In case the remote machine isn't accessible when firing the MessageQueue.GetPrivateQueuesByMachine() call, a System.Messaging.MessageQueueException is raised with the following details

ErrorCode - "-2147467259"
Message - "Remote computer is not available."
MessageQueueErrorCode - System.Messaging.MessageQueueErrorCode.RemoteMachineNotAvailable

If the remote machine is accessible, but the MSMQ service isn't running on that machine, the System.Messaging.MessageQueueException is still raised, but the details become cryptic and are as below

ErrorCode - "-2147467259"
Message - null
MessageQueueErrorCode - "-2147023143"

In case either the remote machine is down or the MSMQ service on that machine isn't running, when you try to send message from your application, the message is stored on a temporary outgoing queue that is created automatically on the local machine. From the application's point of view, the message is successfully delivered. Once the remote machine is up and the MSMQ service successfully running on it, the message from the temporary outgoing queue is automatically delivered. This looks like a good feature, but this also has its own dangers and you can get surprising behaviors. This is mainly because this entire logic is based only on validating the connectivity with the remote machine and a running MSMQ service on that machine. Even if the queue to which you are trying to send the message doesn't exists, the message will still go and essentially vanish since it isn't on local machine anymore and doesn't reach the remote machine, as the queue isn't present anyway.

Another similar issue is let's say the remote queue does exists, but doesn't has write access. Even in that case, the application will successfully send messages without realizing that the message is lost. However none of these issue exist if you are working with local private queues. In such cases, invalid queue names, improper security access rights etc are all validated and appropriate exceptions raised. Hence if you are facing issues of disappearing messages when sending to remote private queues, try running the application on the remote machine itself with the queue path appropriately changed (to point to local queue). This will help identify any queue name or security issues that might be causing the disappearing messages.

Does this means that private queues aren't good to be used? Not really ! They work very well when they are local. In case of remote private queues, the infrastructure automatically doesn't support detecting all error conditions and you have to explicitly verify the right queue name and security permissions.

If you want complete infrastructure support as well for remote queues, you should be considering public queues and not private queues.

Comments

You can use the administration queue and the acknowledge type on a message or queue to get a negative acknowledgement back if anything fails on the remote machine, then you do get to see if something hasn't worked. You just need to set the TimeToReachQueue to something sensible, and if the message hasn't been successfully delivered to the correct queue in that time, it will come back to the administration queue. If used correctly, this can make remote queues reliable.

Is it possible to read from outgoing queue if the remote IP is not valid

Joe, I don't think it will work if the IP is not valid.

The writer does not talk about transactional queues, that have a purpose in some applications. You could not, until v.4.0 of MSMQ in Vista and Server 2008, get a message transactionally from a transactional queue. You would always get an failure exception. Also, security is a big issue with remote queues. Even if I'm in the server admin group and I'm in the sending WS admin group, and the server queue gives full access to that id, you still need to use other built in ids to give access; Everyone and Anonymous logon. This harkens back to the days of configuring DCOM to allow proxy acceess to remote instances of objects; fun fun fun. Still haven't sorted all those remote security oddities out yet. Finally, is the concept of clustered queues and the anomally of the clustered node instance of MSMQ vs. the cluster instance of MSMQ and how the remote designation is overridden by the node computer name. All in all, MSMQ is reliable for data sharing applications. It's a great staging area and the API is fairly simple. Just keep in mind these and other issues when thinking that you can just move your data around your notework without a care. MS only sets the stage. You still have to know how to dance.

When opening a queue to send messages to a remote computer (when dwAccess is set to MQ_SEND_ACCESS), Message Queuing does not check for the existence of the queue.

I did same mistake but changed MQ_RECEIVE_ACCESS
to MQ_SEND_ACCESS and all works fine.
From the MSMQ Docs:

http://msdn2.microsoft.com/en-us/library/ms699817.aspx

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Please key in the two words you see in the box to validate your identity as an authentic user and reduce spam.

Subscribe to this blog's feed

Follow us on

Blogger Profiles

Infosys on Twitter