How to deliver MSMQ messages to a new machine


[[This post applies to traditional MSMQ messaging rather than sending MSMQ messages over HTTP. With the latter you just create a mapping file and you’re good to go.]]


The scenario is that one of your MSMQ servers has had a hardware failure and is down. You have another machine available but it is already in use by other applications so you can’t just rename it or give it a different IP address. What do you do with the messages that have already been sent and are waiting in outgoing queues? 


There are two problems here:



  1. The Outgoing queues are still trying to connect to the IP address of the failed server.

  2. Should the messages somehow be re-routed to the new machine, the address of the messages does not match its computer name and so will be discarded.

and two solutions are available:



  1. Write an application that uses the Local Admin API to pull the messages out of the outgoing queue and create fresh ones for the new machine

  2. Reroute the messages to the new machine and fool MSMQ into accepting them.

 


Developer solution


I don’t write code so you’ll have to work this one out for yourself, maybe starting here:



242471 FILE: MSMQ Local Admin API


“Fooling MSMQ” solution


There are two parts to this solution:



  1. The “next hop” of the Outgoing Queue needs to be changed to point to the IP address of the replacement machine. This is done by changing the IP address that MSMQ is given when it tried to perform name resolution on the destination. MSMQ checks at regular intervals when it can’t deliver messages in case the destination’s IP address is provided by DHCP and has changed through lease expiry. The easiest approach is to add an entry in the HOSTS file that maps the old name to the new IP address and after a while you should see the Next Hop change.

  2. Once the message arrives at the new machine, MSMQ on the receiver will check that the address on the message matches itself. Normally the queue manager will discard any messages that it doesn’t like. This functionality can be disabled with IgnoreOSNameValidation as documented here:



306785 FIX: Message Queuing Messages Are Not Validated with Network Load Balancing


Notes



  • Make sure the queue already exists on the destination machine as MSMQ will not create one just because you have sent the queue manager a message; also the queue name must be the same.

  • Change IgnoreOSNameValidation BEFORE the HOSTS file as otherwise all your messages will vanish  🙂

Comments (5)

  1. Hans says:

    Definitely something I will have to cover with our MSMQ application in the future. Thanks for reminding me and showing a direction!

  2. Bruce says:

    Weird – I tried this today with one of our 2003 sp2 machines and used the hosts file to resolve the server name but it didn’t work, after multiple checks for spelling errors and the like I gave up and renamed the machine.

  3. MSDN Archive says:

    Hi Bruce,

    Were you able to PING the computer name at the command prompt and end up with the IP address in the HOSTS file?

    Were you using the computer’s NetBIOS name or its Fully Qualified Domain Name? I think MSMQ ends up using NetBIOS so I expect this KB article may help explain why your HOSTS entry did not work – using a HOSTS file is 5th in the order of use for name resolution:

    142309 NetBIOS Name Resolution Using DNS and the HOSTS File

    http://support.microsoft.com/default.aspx?scid=kb;EN-US;142309

    Looks like I may need to perform some further testing.

    Other information:

    172218 Microsoft TCP/IP Host Name Resolution Order

    http://support.microsoft.com/default.aspx?scid=kb;EN-US;172218

    Cheers

    John Breakwell (MSFT)

  4. Bruce says:

    Hi John,

    I was able to ping the machine and am fairly sure that the sending machine was able to connect to the receiving machine as I got a ‘queue does not exist or you don’t have sufficient permissions’ error rather than a ‘Remote computer is not available’ error. I tried using both a netbios and fully qualified domain name in the hosts file and got the same result. I didn’t test by using a dns alias which may have been successful but as I understand it, as long as the sender can connect to the receiver (which it could) it then comes down to the receive either accepting or rejecting the message which appeared to be the problem.

  5. MSDN Archive says:

    Hi Bruce,

    Could you please clarify where you saw the ‘queue does not exist or you don’t have sufficient permissions’ error?

    If you are just sending a message then you will not see any errors returned to the application. As you say, the message will be either accepted or rejected at the destination but this does not generate an exception.

    What address do you see for the outgoing queue?

    Cheers

    John Breakwell (MSFT)