In this article I highlight some of the differences between RabbitMQ and ActiveMQ and explain why I am hugely biased towards RabbitMQ.
I’ve used ActiveMQ in production for 3 years and recently made the switch from ActiveMQ to RabbitMQ. Switching to RabbitMQ requires some investment from a code perspective since each technology implements a different messaging specification, however, having made the switch 6 months ago, I feel that the investment was well worth it. I have not looked back at ActiveMQ, my only regret is that I didn’t make the switch sooner.
Let me start off by saying that from a specification perspective, both technologies are very much ‘RONSEAL’; They both “do messaging”, but exactly how they do it is different, and the perceived effort made to achieve those ends in each project differs greatly.
I always pick technology stacks based on how well the technology solves the problem in practice rather than on paper, and favour this over any argument of how modern or established it is. To be clear, I am not a technology hipster, nor am I irrationally fearful of bleeding edge tech. The fact that the tech-stacks I choose happen to be modern has less to do with their “cool” factor and more to do with a belief that modern popular technologies enjoying better overall support stemming from their popularity than their ageing established counterparts. Having said that, I’m open to changing stacks at any time if I see a need to do so, i.e fundamental change in requirements that the existing stack will not cope with, functional regression/instability, high maintenance cost, or an increasing lack of free support.
With this in mind, the reasons for moving from ActiveMQ to RabbitMQ centre around some under-the-hood fundamentals, combined a perceived lack of enthusiasm by ActiveMQ to go beyond the minimum set of requirements to produce a well polished product like RabbitMQ. A common theme throughout this article will be “ActiveMQ does x, but RabbitMQ does it better”. Each of my reasons taken in isolation might not compel someone to switch, but the sum is greater than the whole here; the polish on RabbitMQ makes for a much smoother development experience and as a result I have a lot more confidence in the continued quality of RabbitMQ. Here are the highlights of RabbitMQ.
- Just works out of the box
- Ability to provision easily in puppet
- Native package manager based installation
- Knowledge/Expert principle applied to routing
- Spring integration
It works out of the box
One of the first things I do with any technology is “demo” it, when you’re doing a demo of something, you typically don’t care about the configs and obscure parameters, you just want to see the tool in a sensible default state so you can start tinkering with it as soon as possible. ActiveMQ works out of the box, but RabbitMQ does it better. Like most apache-owned project sites, if you eventually manage to claw your way through the laberynth-like maze that is the ActiveMQ home page, figure out which of the versions is the latest, you might eventually get a hold of the zip containing the binaries. After you read the manual and edit the config file you might finally start the broker and (only because of the JMS spec) be able to immediately post messages to a queue. RabbitMQ’s signposting around artifacts is much clearer, and it’s easy to get hold of and install. Starting a broker on windows or linux comes as part of the pacakge with native runscripts/service mechanisms available, there are proper start and stop scripts to let you run RabbitMQ, and with zero configuration (sensible defaults), a broker can be started immediately.
ActiveMQ give you a choice between a zip file distribution and source code. Rabbit by contrast comes with an native installer for Windows, a .deb file you can download for Ubuntu, or repository information for fetching from RabbitMQ maintained PPAs via the native package manager, an RPM for Redhat people, some artifacts for mac users, and also a plain old zip file. This is a big deal; Aside from windows and all the other distros, ActiveMQ have failed to provide up to date native debian packaged versions of their software, the last package I saw was on Ubuntu 10.04, this package was broken and remained broken for the life-time of 10.04, same story with 12.04. One of the golden rules of Server Provisioning with Puppet is to use the native package, and to avoid the “download -> extract” anti-pattern since this always ends in tears. RabbitMQ provide their own actively maintained debian PPA repositories, this means that not only is the latest upgrades of the software are available to you on Ubuntu from Day 1, it also makes it exceptionally easy to provision a rabbit instance even without any further custom puppet modules. This means you can begin using RabbitMQ with puppet immediately using nothing more than the package expression and an augeus lense. The fact that they go the extra mile and provide a module that lets you configure just about everything under the sun without writing your own augeus lense is just the icing on the big rabbit shaped cake that is RabbitMQ. The 3 or so ActiveMQ puppet modules that do exist work by either downloading and extracting a zip file (see the anti pattern above), or by relying on the debian packages shipped with ubuntu which are massively out of date and just don’t work out of the box - just the bacon bits on the faulty towers waldorf salad that is ActiveMQ.
Routing in RabbitMQ is very different to ActiveMQ. In ActiveMQ, the clients know about the queues they’re sending to, but they also know about how those queues work. For example, the consumer cares about where the message is going and how it’s being broadcast, (Topic, or Consumer). In RabbitMQ by contrast, the clients know nothing about the topology. They know they need to publish to a queue, but they don’t know how the message will be routed and who will consume it, it is the responsibility of a middle entity known as the ‘exchange’ to manage the message routing, and rightly so. Because since when should my clients care about how a message gets routed, clients should not be the experts in routing, this is just another form of unnecessary coupling, and this responsibility should lie somewhere else. If I decide to change the routing, I should be able to do so freely and silently without the clients knowing. The implication here is that you cannot just push or listen to a queue without first having created it, so in this sense RabbitMQ is less “out of the box like” than ActiveMQ as it requires the extra step of creating queues, however, I feel this is a small price to pay for the ability to route dynamically from an exchange.
Both ActiveMQ and RabbitMQ have excellent support within the Spring framework, however, ActiveMQ is an implementation of the JMS spec, whereas RabbitMQ is an implementation of the AMQP protocol (Yes just to be confusing -ActiveMQ and AMQP share 3 letters - pure co-incidence). As a result, you cannot just switch out ActiveMQ for RabbitMQ without first investing in some code changes. Specifically you will need to move from «InsertActiveMQ» to «InsertRabbitMQ», and as part of your configuration process, you will need to configure the creation of the queues in RabbitMQ before you can write to them, the investment is well worth it.
ActiveMQ’ console used to look like a website from the 90’s. Ugly, clunky, form based. They recently improved it, and last time I saw it, it was in beta, and I ended up not being able to do what I wanted, and going back to the classic console. RabbitMQ on the other hand comes with an all-in-one realtime console which is obviously fit for purpose, probably designed from the ground up and not an afterthought.
Try going into the ActiveMQ IRC channel and you’ll see how dead quiet it is. RabbitMQ’s IRC channel actually has people frequenting it, not that this matters, because RabbitMQ just works and you probably won’t need to ask anybody for help ever.