Recently, new plugin for RabbitMQ was created which provides support for delayed messaging. The plugin adds new exchange type to RabbitMQ which will store messages internally, using Mnesia, until they are scheduled for delivery. This provides a protection in case the server goes down. The beauty of this solution is that it keeps everything inside RabbitMQ and doesn’t require installing any additional software. It will also simplify RabbitMQ configuration when compared to solutions based on Dead Letter Exchanges and message TTL.
The plugin is currently in experimental phase, but hopefully community will provide precious feedback and allow it to become production ready.
When you consume messages from [EasyNetQ] bus you do not need to worry about naming and creating queues or exchanges. That’s done for you. The framework will use a pattern when generating name for the queue which is based on strongly typed name of the message type and consumer’s subscription id. Similar happens when generating exchange name. But is there anything you can do to change this behaviour?
Using Advanced bus
[EasyNetQ] gives you an Advanced bus which allows to manually create and manage queues, exchanges and bindings. You can use it to control queue names but it may be an overkill if you want only to control names.
When the bus has to resolve queue or exchange name it is using an instance of IConventions type. The standard implementation takes strongly typed name of the message type and appends subscriber’s subscriptionId to the end. By providing own implementation you can control the way exchange and queue names are generated.
The IBus interface from EasyNetQ framework has SubscribeAsync() method which allows easily to span message handling between different threads. It uses standard TPL Tasks for delegating handler execution. Depending on the application, you may create Tasks with LongRunning flag, which provides a hint to the scheduler that additional thread may be required1 and it should avoid using a ThreadPool2. Below example shows how to register parallel consumer:
var bus = RabbitHutch.CreateBus("host=localhost");
bus.SubscribeAsync("sub1", message => Task.Factory.StartNew(() =>
// long running message handler
Few people have asked me already how to start using [RabbitMQ] in .NET, so I decided to write a short post about it.
First, visit erlang’s page, download erlang distribution according to your system (either 32 or 64 bit) and install it. If you have 64 bit machine (and you really should have) than get the 64 bit distribution, otherwise erlang process won’t be able to address more than 2GB of memory.
Next download RabbitMQ server and install it. I strongly recommend to install Management Plugin, which comes with [RabbitMQ] installation. All you need to do is run following command from command prompt (you may have to navigate to RabbitMQ’s sbin folder):
This is the second post in series about [EasyNetQ]. In the [first post] I am explaining how to install [RabbitMQ] and write simple application which publishes and consumes string messages.
Complex type message
Usually you will need to send more complex types than string. Fortunately it is no harder than sending string messages. All you need to do is to create library project which will contain your message types and share it between publishers and consumers.
Load the example application you made in the [first post] and add new Class Library project to the solution named Messages. Add new class PersonName to that project which will represent persons name:
When designing your system you have few options on how the messages will be delivered to your consumers:
messages are delivered in round-robin fashion – this is a great option for distributed, load balanced processing;
messages are delivered to all consumers – this is the option to use if there are different processors for given message;
hybrid solution where some consumers are getting messages in round robin fashion and other are getting all messages;
In the round-robin delivery, the messages are automatically distributed between all consumers. By manipulating prefetchcount setting you can easily achieve load balancing. This scenario is great when there are many consumers doing the same type of processing. The example will be an order fulfilling system with few processors receiving orders. In the heavy load times you can spin extra consumers to cope with additional work, and the system will automatically deliver next message to free consumer using round-robin fashion.
This post was written as an answer to one of the questions on EasyNetQ user group.
The main principle of EasyNetQ bus is simplicity. It greatly abstracts nuances of communicating with RabbitMQ giving developers time to concentrate on writing the core application. The framework is great and makes processing messages really simple. But there are few scenarios when this simplicity becomes a small pain. One of those times is when you want to gracefully stop the application allowing it to finish processing current message.
This post is rather lengthy but I wanted to provide good explanation.