Wednesday 11 February 2015

How MSMQ saved my day (and my application too!)

Have you ever tried opening twenty applications on a 1 GB RAM machine? Or tried transferring five blue ray movies in five different windows on that same machine? “Why would you do that, that’s gonna kill your machine!” I can hear some of you saying. I did something similar a couple of days back when I had to send an email to 5000 people. Now I know what you are thinking. Sending mails ain’t rocket science! I agree. But sending it to 5000 people would’ve made my web application unresponsive and I simply could not afford that. I needed a workaround, and that’s when I instantly thought of MSMQ!

MSMQ: My Saviour (Microsoft) Message Queue

Microsoft Messaging Queue (MSMQ) is a message storage area which can be used by one or more than one applications to store and retrieve messages. I used MSMQ to store all the emails on a button click and then wrote a windows service to send the mails to all my recipients. Sending these records to MSMQ queue was not a time consuming job, so it was done rather quickly and the application was free to service the next user request.

Basically, my Web Application would now send the messages to the queue and then be free to execute the next request made by the user. A Windows service continuously running in the background would send the emails (and do the time-consuming job, without killing my application!). 


First things first: Installing MSMQ

Before I show you how to make MSMQ work, let me first show you how to install it properly.

Step 1:
Go to Control Panel –> Programs –> Turn Windows Features On or off

Step 2:
Select Microsoft Messaging Queue (MSMQ) Server

This will install MSMQ on your machine.

Creating a Queue

In order to create a new queue, simply right click on My Computer and select Manage, as I have shown below:

You can also create a queue through programing using a System.Messaging namespace. If you are working on Visual Studio for Web, you might need to add this DLL from C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1. 

For creating a new queue, you will need to specify a queue name in a specific format. The queue name needs to start with a “.” and should have a “$” after private, as shown below in the example. 


e.g. “.\\Private$\\Queue1”

The above code will create a new queue if it does not already exist.

The battle begins: Inserting Messages in the Queue

Now came the crunch part: to insert messages in the queue I just created. I used the following code snippet to insert the messages into my newly created queue:

The above code will give you an exception if queuing is not enabled. I also created a class EmailMessagedata where I set all the properties like emailID, subject, body etc. You can use the following code snippet for the same:


Providing the finishing touches: Retrieving Messages from the Queue

Now all I had to do was to retrieve these inserted messages and send mails or perform the required operation. I retrieved all the messages from Queue1 and saved them in an array, and then deleted all the messages in Queue1 using purge().

You need to add a reference to the Web Application’s DLL using which you can insert the message in the queue to get the message content in the format specified in your EmailMessagedata class.

My takeaway

Using this approach, I was able to save a lot of time as all my emails were stored in the MSMQ. I did not have to wait while my emails were being sent; I was able to continue using the application while the windows service was sending the emails in the background. All this while, my application remained responsive. If you need to execute time consuming tasks, I would recommend you use MSMQ. Just as it saved my day, I am sure it will save yours too.



Written by Manish Patil, Dotnet Developer at Eternus Solutions

9 comments:

  1. "The queue name needs to start with a '.'" - The '.' represents localhost, there is a variety of URIs that you can use to get to a queue. https://technet.microsoft.com/en-us/library/cc778392.aspx Cheers!

    ReplyDelete
    Replies
    1. Hi Houghtelling,
      I believe using '.' was easier for Manish instead of writing the computer name. Otherwise, as you mentioned, we can use a variety of URIs.

      Delete
  2. I still dont get it. How does MSMQ help over here. We have a similar scenario where the website writes the email to be sent to a sql database and we have a windows service which polls the database to see if there are any email messages to be sent. If there are any messages to be sent then the windows service retrieves the email data from the database and sends it. How can i benefit from MSMQ. If we do use MSMQ would this add an additional layer of complexity to our app.

    ReplyDelete
    Replies
    1. I am not backend expert, but I know a little about it. MSMQ helps the same way as using a string helps over a character-array - it helps you focus on just your business problem and abstract some of the other thing away. MSQM will do the long-polling for you and manage the requests. You will not have to configure SQL and windows service and other things to the extend you are doing. Yes, it may be overkill for a simple project; but when that project grows, you may have a hard time maintaining it or porting it over to a messaging service.

      Delete
    2. Hi maams,
      As compared to database tables, queues provide high performance, high concurrency and load balancing, enabling you to process thousands of messages per second concurrently. In short, with the help of MSMQ, you can implement this process asynchronously and efficiently. Let me elaborate how.

      1. Imagine multiple users writing to the same table in database concurrently. It will create performance issues if the number of users is a quite high. Here MSMQ can be a good alternative for database table.

      2. Additionally, consider a situation where you are trying to insert a message in the database and you lose connectivity. The record won't be inserted as you can only insert a record in the database when you can connect to a database (To increase scalability, database is generally on its own server), whereas if you use MSMQ, it will store the message in its queue as the queue is stored locally.

      Using database table to store messages is a good option if you have a workflow situation (e.g. mails are to be authorized by managers before sending) as it is easy to query. The above workflow can be implemented using MSMQ but it will require multiple iterations to check which mails are yet to be authorized.

      If you want to use a database table to store messages, MSMQ can be used to solve the two issues that I mentioned above. You can first store the messages in MSMQ and then insert the messages in database table from MSMQ. In this way, you will have only one client writing in the database at a time and if you lose connectivity with the database, MSMQ will hold the messages and will insert in database when connection is restored.

      Delete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Thanking you for finding this solution

    ReplyDelete
  5. Glad it was of use to you guys.

    ReplyDelete