[[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:
- The Outgoing queues are still trying to connect to the IP address of the failed server.
- 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:
- 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
- Reroute the messages to the new machine and fool MSMQ into accepting them.
I don't write code so you'll have to work this one out for yourself, maybe starting here:
"Fooling MSMQ" solution
There are two parts to this solution:
- 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.
- 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:
- 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 🙂