RabbitMQ is a general-purpose message broker that supports multiple messaging protocols. It uses a message queuing mechanism to enable communication between different services in the software applications. Its high throughput capabilities make it an excellent choice in the microservices environment where we may want to scale individual system sections. Let’s explore the riveting world of what is RabbitMQ and dig deeper into its unique traits!
2. RabbitMQ Architecture – Example
RabbitMQ works as an intermediary between different parts of an application, allowing you to create complex communication patterns. It includes a rich plugin ecosystem for implementing features like authentication, monitoring and routing, making it flexible enough to fit almost any requirement. All these features are packed up in a well-thought-out architectural structure that enhances reliability and scalability without compromising performance.
By having a RabbitMQ broker between two services, we can create an architecture that facilitates data transmission. With one service sending messages to the message queue and another potentially consuming some or all of those same messages, publishers can channel a message into its required queue through the routing key.
Once a message is consumed, it will get acknowledged and, as a result, removed from the queue. A RabbitMQ message queue is fastest when empty; therefore, consumer scaling is a typical approach when processing consumers who cannot cope with the messages being produced.
2.1 Supported Messaging Protocols
One of the benefits of using a message broker like RabbitMQ is that it provides a variety of messaging protocols that enable message exchange between applications and systems.
At first the Advanced Message Queuing Protocol (AMQP) was initially supported; however, more have been added since as plug-in add-ons. For example, MQ Telemetry Transport (MQTT), Streaming Text-Oriented Messaging Protocol (STOMP), and WebSockets are now available with the RabbitMQ server.
2.2 What is Publisher Application
A publisher application in RabbitMQ could be a web application that receives messages from many sources and routes them to an exchange. This exchange accepts messages and serves as the hub of message flow, which then passes these messages over its multiple queues.
A publisher application receives and routes these messages according to the routing rules established by the user. It’s a powerful tool for organizing and prioritizing your messaging queues so that you can get the most out of your RabbitMQ server infrastructure.
2.3 What is Consumer Application
A consumer application in RabbitMQ receives messages from message queues. This is done through exchanges and message attributes, allowing users to route their messages however they want. With this functionality, users can create a message flow upon which the consumer can receive messages that match the criteria laid out by the developer.
Once a queue receives messages, it’s up to the consumer to consume them; consuming it will remove it from the queue and make it unavailable for other applications. This function allows consumers to efficiently receive and manage their exchange messages in RabbitMQ.
3. RabbitMQ Broker Charakteristics
RabbitMQ messaging system uses a push model to push messages to the consumer. The consumer uses prefetch and batch size settings to control outstanding messages and how often to process successfully. Is it essential to configure prefetch correctly so we don’t overwhelm the consumer.
The default batch size in Spring is set to 1, so we get an ack after each message. Changing this setting will improve performance, but it’s possible to have duplicate deliveries in the event of failure.
3.1 Message Queueing
RabbitMQ operates on message queues that enable web servers to respond swiftly to requests instead of expending precious resources upfront, which may delay response times.
A message queue is a behind-the-scenes data structure managed by the broker that stores messages until they are acknowledged or consumed by the receiver. The message header attributes determine how messages can be moved from queue to queue, which enables the receiver to receive specific messages.
3.2. Message Routing Pattern
One of the main advantages of RabbitMQ is the flexible routing mechanism. Different exchange types have different routing rules determining which queue a specific message will be placed in. Four exchange types are available: Fanout, Direct, Topic and Headers exchange.
When a publisher sends a message to the exchange, it will pass the routing key. This routing key determines the destination queue for a message. Single exchange can route messages to multiple queues where each queue takes the messages whose routing key matches the binding key. Binding links exchange with a message queue to define the type of messages in which this particular queue interests.
Depending on the exchange type, an exact match or wildcard of only part of the routing key can guide messages directly. This means you do not need a precise matching between all parts of the routing key for your message to find its destination.
The fanout exchange routes messages without a routing key, so all linked queues automatically receive messages.
3.3. Message Processing
In RabbitMQ, the order of messages in a queue is not guaranteed. When there is more than one consumer in a queue, the consumers compete for the messages. Once one consumer obtains the message from a queue, it will be removed automatically. The message will get acknowledged regardless if processing has been successful. Hence, we need to provide appropriate handling if it’s not. A common approach is to route error messages to the separate holding queue (DLQ) to be analysed and repossessed later. Here is a good practical insight into error handling with Java and Spring.
The listener may fail to obtain the message from a queue. Imagine getting a JSON message that is serialised into a Java class. When such a message is not in the expected format, the serialisation will throw an exception, and as a result, the consumer will respond with a negative acknowledgement (nack). The message gets enqueued back to get a queue for reprocessing unless configured otherwise, as this is the default behaviour—more about RabbitMQ acknowledgements.
3.4. Message Priority
The message publisher can set the priority of the publishing messages. Each message with a priority set is sent to a priority queue, which is a regular queue with additional integer parameters between 1 and 255 to indicate the maximum priority supported. The prioritisation of messages only occurs when the consumer applications cannot cope with the load and messages are in a queue waiting to be processed. Those with higher priority will be consumed and processed first.
3.5. Consumer Scaling
Consumer scaling in RabbitMQ refers to the ability to automatically create new consumers when there is an increase in message traffic. This helps ensure that an application can always handle increased demand.
If the messages sent to your queue exceed the rate at which they are consumed, you will be left with a backlog of unprocessed messages. This is detrimental to performance since RabbitMQ runs faster when queues are empty, and if too many messages build up, it can cause out-of-memory errors on the broker. To combat this problem, it helps to scale consumers – adding extra ones so that all waiting messages can be dealt with as quickly as possible!
Consequently, it is one of the most effective ways to manage workloads and keep communication efficient during sudden high demand.
4. RabbitMQ Spring AMQP
Spring AMQP is an open-source project that enables developers to use the popular RabbitMQ messaging platform in their web applications. It simplifies the setup process, allowing developers to configure new connections to RabbitMQ with little effort quickly.
It offers additional features such as out-of-the-box message conversion and caching for improved performance. Developers can also tie transactions and message acknowledgements into advanced Spring lifecycle services like JTA transactions and request scoped beans.
With an active community contributing examples and tutorials, Spring AMQP gives developers access to a powerful messaging service at a minimal cost.
This article explored what is RabbitMQ and its unique characteristics. We’ve discovered how this innovative broker can be a message-passing middleman between different services. We also learned about key features such as routing, processing, scaling and priority optimisation!
Daniel Barczak is a software developer with over 9 years of professional experience. He has experience with several programming languages and technologies and has worked for businesses ranging from startups to big enterprises. Daniel in his leisure time likes to experiment with new smart home gadgets and explore the realm of home automation.