RabbitMQ is a message broker, allowing asynchronous communication in distrubuted systems. The key advantages of RabbitMQ include: 15 years of open source history, battle proven Erlang implementation and support for industry standard protocols. RabbitMQ is among the most popular implementations of message brokers. Others include ActiveMQ for Java, celery for Python and Kafka - if you consider it a message broker. Also, pretty much all cloud providers have their proprietary implementations, like, Google Pub/Sub, Amazon Kinesis, Azure Service Bus and so on. RabbitMQ at its core implements AMQP, a standard protocol for information interchange. So not only it’s open source, it’s also built on top of open standards.
There are a few key abstractions you must understand when working with RabbitMQ. These are: exchanges, queues and bindings. When sending messages to Rabbit, you send them to an exchange. Exchanges then route these messages to queues bound to them. The role of the exchange is to perform more or less sophisticated routing. For example, so-called fanout exchange will forward every message to all bound queues. On the other hand, direct exchange routes messages to queues bound with a specific binding key. Each message has a key, so you can easily route by that key.
There are more sophisticated exchange types. Moreover, an exchange can be bound to another exchange, forming a more complex routing topology. All this logic is implemented inside the broker, so it’s pretty fast and reliable.
Talking about reliability, the consumer side is also interesting. First of all, when consumer receives a message, it should be acknowledged. Otherwise, the message goes back to the queue and is retried. This prevents message losses. On the other hand, if the consumer keeps failing to acknowledge the message, it is routed to DLQ. Dead Letter Queue.
Depending on your exchange and queue configuration, you can implement multiple patterns in RabbitMQ. For example, let’s say your consumer has multiple instances. If each instance has its own dedicated queue bound to fanout exchange, we got ourselves a broadcast. On the other hand, if all nodes listen to the same queue, each message is forwarded to a single node only. Moreover, if all consumers are down, messages will patiently wait for them to go back online.
Messages brokers work best when asynchronous style of communication is needed.
Let’s say you are requesting a long-running operation to start.
However, if you desperately need a synchronous result of sending a message, this can be implemented as well.
Although, it’s not recommended.
When sending a message you may either define a
reply-to queue or send a correlation ID.
In the former case each message creates a unique, temporary reply queue.
In the latter case, a single response queue is used, but the producer may correlate which request was responsible for a certain response.
That’s it, thanks for listening, bye!
- RabbitMQ on Wikipedia
- RabbitMQ official website
- RabbitMQ vs Kafka Part 2 - RabbitMQ Messaging Patterns (2017)
- RabbitMQ vs Kafka Part 5 - Fault Tolerance and High Availability with RabbitMQ Clustering (2018)
- Message broker on Wikipedia
- Cloud message brokers: