RabbitMQ is the most widely used, open-source message broker, used by developers to integrate different systems and components of a service. It is used to process messages asynchronously in form of a queue.
Messages in RabbitMQ are enqueued and dequeued (delivered to consumers) in the FIFO manner. It means in the RabbitMQ message are delivered in order for the given exchange and message queue. But FIFO ordering is not guaranteed priority and sharded queues by multiple exchanges and consumers.
In a shared queue when a single queue is connected to many clients and messages are consumed by those clients in parallel then processing order can not be guaranteed.
In order to achieve ordered processing, it is important to process one queue by exactly one consumer, and queues should bind to only one exchange. This can be achieved by consumers connecting to RabbitMQ with specific flags.
For ordered message processing RabbitMQ provides two types of connection using parameters.
- Exclusivity: This can be used when only one exclusive cannection to queue is required, This allows to make sure only one consumer at a time consumes from the queue. When registering a consumer with an AMQP 0-9-1 client, the
exclusive
flag can be set to true. The call succeeds only if there’s no consumer already registered to the queue at that time. In case of consumer lost connection or terminated, then application is responsible to register new consumers. - Single Active Consumer: Single active consumer allows to have only one active consumer at a time consuming messages from a queue and to fail over to another registered consumer in case the active one is disconnected or terminated. This is useful when messages must be consumed and processed in the same order they arrive in the queue.
Java, dotnet, and other RabbitMq clients support these using parameters.
RabbitMQ and Spring Boot Exclusive Consumer Example
In the Spring Boot application based on your design and requirement, you can use any of the above options.
For the Spring Boot, and RabbitMQ example refer to this post. RabbitMQ Hands-on Tutorial with Springboot – code4copy This can be done as given below.
For making an exclusive connection to the queue you just need to create a queue using the following overloaded bean method. This means this queue will be used by only this consumer.
@Bean(name = "queue1")
Queue queue1(){
// Durable false, not survive server restart
// Exclusive connection true
// Auto delete true
return new Queue(queue1, false, true, true);
}
In the above bean, all parameter definitions are given below.
- name – The name of the queue.
- durable – true if we are declaring a durable queue (the queue will survive a server restart)
- exclusive – true if we are declaring an exclusive queue (the queue will only be used by the declarer’s connection)
- autoDelete – true if the server should delete the queue when it is no longer in use
So for exclusive connection uses exclusive parameter true.
RabbitMQ and Spring Boot Single-Active Consumer Example
For single active consumer can be set via setting parameter x-single-active-consumer to true while declaring queue. In Spring boot this can be done as given below. One can set other parameters in the map as given below.
@Bean(name = "queue2")
Queue queue2(){
// Durable false, not survive server restart
Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-single-active-consumer", true);
return new Queue(queue2, false, false, false, arguments);
}
You can check the complete working example at Git hub
After running the above example you can check in the RabbitMQ management console, that two queues have been created, one with AD(auto-delete) and Excl(Exclusive consumer) and the other with SAC(Single active consumer) features.