Skip to content

Instantly share code, notes, and snippets.

@alvatar
Forked from Dev-Dipesh/rabbitmq_notes.md
Created October 14, 2022 13:43
Show Gist options
  • Save alvatar/57397c5e26f8837d01a742acde024f37 to your computer and use it in GitHub Desktop.
Save alvatar/57397c5e26f8837d01a742acde024f37 to your computer and use it in GitHub Desktop.
Why RabbitMQ is better over Redis and notes on RabbitMq.

Redis is Database whereas RabbitMQ was designed as a message router or message-orientated-middleware (mom), so I'm sure if you look for benchmarks, you'll find that RabbitMQ will outperform Redis when it comes to message routing.

RabbitMQ is written in Erlang which was specifically designed by the telecom industry to route messages, you get clustering out of the box due to it being written in Erlang which means in a clustered environment, RabbitMQ will outperform Redis even further.

Furthermore, you get guaranteed delivery of messages due to the AMQP protocol, in other words, if the network drops while consuming the message, the consumer won't be able to say thanks for the message, so the consumer will drop the message and Rabbit will requeue the message, if you publish a message and the queue didn't say thanks to the publisher due to network problems or timeouts, Rabbit will drop the message and the publisher will keep on trying to publish the message. You can have publish retries with backoff policies, so retry in 5 seconds, then 10 seconds, then 25 seconds, etc.

If you do manage to fill up the queue, Rabbit will block you from publishing any further messages until space becomes available (on a machine with enough ram, that could be in the billions of messages)

You have two modes on the queues, persistent queues, and in-memory queues, if that data is critical, you can enable the persistence flag which will persist the data. On persistent queues, only once the message is persisted will the publisher be notified that the message was received. If you don't like the built-in database, you can plug your own database in. Further, if you're running in a clustered environment, you can add redundancy to your queues, so if one RabbitMQ server dies, the messages are already on the other queues (in other words you have 10 Rabbit servers running behind a load balancer, you can have your message sync to all servers before being allowed to be consumed and if you take one down for maintenance or the server goes up in flames, things will continue to work)

You have advance routing schemes, direct routing will route it directly to a queue. If legislation wants me to now all of a sudden log every user transaction; without changing any code, I just change the direct exchange to a fanout exchange which then copies the message to the queue it should be going as well as to a logging queue and let my logging application log those message. If legislation changes again and now doesn't want European customers transacting in the African region, using the headers exchange, I can look at the message header and reroute the message to a different processor.

If my email provider is offline and I'm having networking issues, I can use the shovel plugin to shovel all the messages from one RabbitMQ instance via a rerouted secure link to another instance of RabbitMQ somewhere else in the world and the applications there can start processing the emails.

I can have topic exchanges, we use topic exchanges for logging, we log all messages with a topic like this: INFO/WARN/ERROR:package. Now using the topic exchange, I can route all messages to one queue where it'll be picked up and written to disk. All warning messages are packed into an email and sent out once a day using WARN:#, all ERROR:# are routed to a queue where we'd get an SMS notification as soon as an unexpected error occurred so that we can improve our infrastructure to handle those errors better. ERROR:com.mycee.sms.# we route to the email queue so it emails us about the sms application failing. ERROR:com.mycee.heartbeat errors we route to a monitor queue that needs to know about heartbeat errors. Etc etc.

You get virtual hosts on your RabbitMQ which means you can separate things, but still shovel messages from one virtual host to another if you need to, so if contractors are working on your system, you can shovel the messages they need onto a separate virtual host and they won't get access to any of your other queues while the system continues to operate.

I can expire messages on the queue, if something hasn't been processed in 15 seconds, kill it, if it's email and the email had to be sent before a certain date (for example 1 day special), I can add a timeout in the message which will axe the message if it's still on the queue past a certain time / date then and also specify a routing scheme to reroute all expired messages to a dead queue where I can decide what to do with them.

Everything I just mentioned, plus a lot more can all be done via the Admin UI where you can also look at pretty graphs of what's happening on your queues, so you don't need access to the server to make changes, just admin permissions on your account and you can reroute messages to where they need to go.

So these are a few of the reasons I like RabbitMQ (there's many more, but I don't want to make the post too long). RabbitMQ is the complete package when it comes to message routing.

So here's a checklist, if you answer yes to any of these, RabbitMQ or any other AMQP-based server would probably be a better fit for your needs:

  • Do you need persistency?
  • Do you need transaction support?
  • Do you need distributed transaction support?
  • Do you need "once and only once" delivery semantic? At most once? At least once?
  • Do you need multiple retry policies (linear delay, exponential backoff, etc ...)?
  • Do you need exception/dead queues?
  • Do you need item retention?
  • Do you need queue browsing support?
  • Queue administration capabilities?
  • Do you need item priority management?
  • Do you need automatic item expiration?
  • Do you need delayed items?
  • Do you need item sequencing? Last value queues?
  • Do you need publish-and-subscribe (RPC style)? With multi-casting?
  • Do you need to dequeue from several queues at the same time in a single thread?
  • Do you need high-availability and/or clustering support?
  • Do you have a high-throughput?
  • Do you need the best performance?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment