Introduction
I have been working on implementing a WCF which would send messages to a remote/local queue and at destination, another service which would listen to the respective queue and process it. Basically, my requirement was as depicted in the diagram.
Apart from the above, we have to implement fail-over cluster for MSMQ server.
Background
MSMQ is an inbuilt feature in Enterprise servers, they are reliable message delivery systems.
Please go through the same if you are not familiar with it.
Using the Code
Sending of the message:
MSMQMessage message = new MSMQMessage{Id="xyz",etc..}();
ChannelFactory<IMSMQHelper> cf = new ChannelFactory<IMSMQHelper>("MSMQDestination");
cf.Open();
IMSMQHelper msmqClient = cf.CreateChannel();
MsmqMessage<MSMQMessage> messageToSend = new MsmqMessage<MSMQMessage>(message);
msmqClient.SubmitMessage(messageToSend);
The above piece of code uses channel factory to send message via the binding "MSMQDestination
".
Please note that MSMQMessage
is my custom class.
In case of multicast queue
<endpoint address="msmq.formatname:MULTICAST=234.1.1.1:9090"
binding="msmqIntegrationBinding" bindingConfiguration="msmqBinding"
contract="IMSMQHelper" name="MSMQDestination"/>
In case of unicast queue:
<endpoint address="msmq.formatname:DIRECT=TCP:192.168.150.155\private$\MyQueue
binding="msmqIntegrationBinding" bindingConfiguration="msmqBinding" contract="IMSMQHelper"
name="MSMQDestination"/>
If you look carefully, there is a difference in address definition in both the cases.
You might be wondering how to create a multicast queue?
Well, you have to create a queue first and later go to its properties > multicast - assign a multicast IP and port here (remember all the queues should have the same multicast IP to form a group).
Receiving of messages:
MSMQMessage messageBody = new MSMQMessage();
public void SubmitMessage(MsmqMessage<MSMQMessage> message)
{
messageBody = (MSMQMessage)message.Body;
}
Above is the method in agent service, if you see the SubmitMessage()
method is the same as what we use to transport the message from our client service.
End point at agent service:
<endpoint address="msmq.formatname:DIRECT=OS:.\private$\MyQueue"
binding="msmqIntegrationBinding" contract="IMSMQHelper" bindingConfiguration="ServiceBinding"/>
Here, address points to local as we are running agent in the same server.
This end point makes the service listen to incoming messages in the mentioned queue, i.e., "MyQueue
". Make sure end point is under services
tag:
<services>
<service>
<endpoint ...>
<service>
<services>
To support net.msmq
activation, the Web site must first be bound to the net.msmq
protocol.
So, Agent has to enable this protocol.
Points of Interest
Sending and receiving messages is quite easy, but I faced a lot of problems while clustering the service. It may be because I had no clustering experience before, but finally was able to set up a clustered MSMQ.
Note: I am using Windows 2008R2 Enterprise Servers.
Before enabling of MSMQ as cluster service, we need to have few prerequisites. These are as follows:
- Atleast 2 enterprise servers as failover clustering is a feature only available in enterprise servers.
- We should have a server cluster with at least 2 nodes (please consult a server admin) and turning on failover cluster service.
- We should have atleast one cluster drive.
- MSMQ feature should be turned on in all the node servers.
Once these prerequisites are fulfilled, we can start configurating MSMQ service as cluster service.
Configurating MSMQ as Cluster Service
Follow the steps given below:
- Open failover cluster management, and add MSMQ to the service cluster with the help of add service configuration option in the interface.
- You have to assign a virtual IP to the cluster and add a cluster drive as a process, then the nodes are to be selected.
- Once all these processes are done, use finish button to initialize the cluster.
After the cluster is created, please use the chosen virtual IP used during configurating MSMQ cluster for managing MSMQ Queues, from computer management interface. (That will be using the virtual IP to login, running the MSMQ on a cluster level.)
No need to replicate queue in all the nodes once the failover happens, the next node takes over and will persist all the messages before failover.
History