Now that Rebus officially supports RabbitMQ, I’ll just outline some of the reasons why you might want to choose one over the other… here goes:
Pros of RabbitMQ
The Rabbit is faster!
In my experience, RabbitMQ is often slightly faster than MSMQ in simple scenarios. I know that people pump high volumes of messages through Rabbit every day, and people might throw around numbers like “100000 msg/s”, or “500000 msg/s” and stuff like that. It might be true, but I promise you that these volumes can only be achieved in a few cases where e.g. a bit of delivery guarantee, message durability and/or atomicity is traded for speed.
RabbitMQ is easier to scale out, though – where MSMQ doesn’t handle competing consumers very well, it’s definitely the way to go with Rabbit if you have to process large message volumes concurrently.
Rabbit is (in some ways) easier to manage
RabbitMQ is pretty easy to manage because it’s a server that is installed somewhere, and then you point all the clients to the broker and they’re good. It’s easy to just run it on port 5672, and then that’s the only port that needs to be opened for access through firewalls, across VLANs, and whatnot. Most serious installations will require at least two Rabbit nodes though, so you might need to account for some configuration time though.
It also comes with a fairly useful web-based management tool that allows you to inspect all queues on the Rabbit server. This centralized way of managing things just makes it feel like you’re in control.
RabbitMQ can be configured to route messages in many ways, and Rebus can leverage the multicast features of Rabbit to function as a global subscription storage. This means that you can do this:
.Transport(t => t.UseRabbitMqAndGetInputQueueNameFromAppConfig("amqp://some_hostname")
(notice the “ ManageSubscriptions” above?) which will make Rebus use Rabbit to do the hard work when doing pub/sub. I’ll get back to this in a future blog post, I promise 🙂
Pros of MSMQ
MSMQ will probably be more reliable in most scenarios, because applications are always talking to the locally hosted MSMQ service. I.e. MSMQ always does local store-and-forward of messages, which means that you can always count on being able to deliver a message – and that’s actually something!
MSMQ is inherently more distributed – i.e. it’s much more tolerant to machines rebooting, switches failing, etc etc – if it can synchronize messages across the network, it will do so – if not, it will back off and wait until it can do so again.
Works well in homogenous environment
And then, if you’re so lucky that your network consists of one LAN with Windows machines, then everything will just work! And that includes security with user rights on queues, etc.
Easy to install
Oh, and then MSMQ frickin’ comes with Windows out of the box. That’s pretty cool 🙂
I hope to see both the MSMQ transport and the RabbitMQ transport thrive and prosper. I hope to use both myself, and I’d like to help people use both as well.
That was a long post! I hope even more people will find Rebus useful now that it can work with RabbitMQ. As always, just go get the bits from NuGet by doing the usual install-package rebus.rabbitmq.
3 thoughts on “Rebus transport: MSMQ vs. RabbitMQ”
You are writing as a pro of MSMQ that it is more reliable and utilize local store and forward, this is possible with RabbitMQ too using the (beautifully named) Shovel plugin http://www.rabbitmq.com/shovel.html
Furthermore the installation of RabbitMQ is easy to if you ask me, not out-of-the-box windows but difficult would be a stretch 🙂
Last but not least one pro of RabbitMQ i think is worth mentioning is the rabbitmq_management plugin. Enable it and you have a web based management tool, i know the information and functionality is available for MSMQ too but it just comes out of the box in RabbitMQ which is really nice.
Right – if I understand this correctly, you would then install RabbitMQ locally on all client machines (i.e. on those that require the broker to be available) and then configure Shovel to move messages to the central broker?
I guess that is pretty neat!
I see the availability thing as the main disadvantage of Rabbit. And then I’ve coded some stuff in Rebus that will automatically do failover between nodes in a Rabbit cluster, but still you’ll have to publish (and fail!) at least once before failing over, and overall it’s just not an elegant solution.
Also, “Shovel” IS a really cool name!
In theory the availablity thing isnt a library task if you ask me but an infrastructure task, basically i would use shovel as described and if i really need to have a HA solution where i can’t have RabbitMQ on the clients then i would but two or more RabbitMQ nodes behind a load balancer to ensure its availability when publishing.