RabbitMQ is an open source message broker software. It accepts messages from producers, and delivers them to consumers. It acts like a middleman which can be used to reduce loads and delivery times taken by web application servers.

Here P is Producer, C is Consumer and middle one is queue.

Steps for producer to send messages :

1) Create a connection to Queue

ConnectionFactory factory = new ConnectionFactory();

factory.setHost(“localhost”); // IP of the machine

Connection connection = factory.newConnection();

Channel channel = connection.createChannel();

2) Specify name of Queue to which we want to send our message and publish message to queue

channel.queueDeclare(QUEUE_NAME)

String message = “Hello World!”;

channel.basicPublish(“”, QUEUE_NAME, null, message.getBytes());

3) Close channel and connection

Steps for consumer to receive messages :

1) Create a connection to Queue

2) Specify name of Queue to which we want to consume our message

3) Since queue will send us messages asynchronously, we provide a callback in the form of an object that will buffer the messages until we’re ready to use them

Consumer consumer = new DefaultConsumer(channel)

> Consider an example of two consumers connected to one queue, both of them will get tasks from queue, but in what order? RabbitMQ distributes messages in round-robin manner i.e it sends each message to the next consumer, in sequence. On average every consumer will get the same number of messages.

> RabbitMQ removes tasks delivered to a consumer from its queue, so what happens if worker dies with it only partly done? To handle it, there is an option : “acknowledgement”. An ack is sent back from the consumer to tell RabbitMQ that a particular message has been received, processed and that RabbitMQ is free to delete it.

> While distributing tasks, what happens if all even messages are heavy and requires more time compared to odd messages?. One worker will be constantly busy and the other one will do hardly any work. Right! .. To overcome this situation, we can use

int prefetchCount = 1;

channel.basicQos(prefetchCount);

This ensures that RabbitMQ doesn’t deliver more than one task to one worker at a time. So it will check for acknowledgement from workers and don’t dispatch a new message to a worker until it has processed and acknowledged the previous one. Instead, it will dispatch it to the next worker that is not still busy.

RabbitMQ EXCHANGE

In actual case, working of RabbitMQ is that producer sends message to “EXCHANGE” and exchange pushes it to multiple queues and workers get message from queues to which it has binded with.

Now instead of publishing directly to queue, producer now publish messages to exchange. Exchange delivers messages to queues based on exchange types. Different exchange types are direct, topic, and fanout.

While publishing messages to exchange, producer has to specify the type of exchange we are going to use like,

channel.exchangeDeclare(“logs”, “fanout”); //logs is the name of fanout exchange

channel.basicPublish( “logs”, “”, null, message.getBytes()); //publish message to exchange

and can also define routing key, means to which all queues particular message should be routed like,

channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());// here severity is the routing key

Relationship between exchange and a queue is called a binding, and uses binding key to define it.

The fanout exchange just broadcasts all the messages it receives to all the queues it knows. It simply ignores binding value since it forwards messages to all queues.



In direct exchange, a message goes to the queues whose binding key exactly matches the routing key of the message. In fanout exchange, routing key would be null since exchange delivers messages to all queues, so no routing is needed.



In above example, if message published to exchange is with routing key orange, it will be delivered to only first queue Q1 whose bindingkey (orange) matches routingkey.

Topic exchange works same as that of direct exchange but difference is

* routing based on multiple criteria

Consider example shown below:



*means exactly one word and # means zero or more words.

In above example,

Q1 is interested in all the orange animals.

Q2 wants to hear everything about rabbits, and everything about lazy animals.

A message with a routing key set to :

“quick.orange.rabbit” will be delivered to both queues.

“lazy.orange.elephant” will go to both of them.

“lazy.brown.fox” only to the second.

“quick.brown.fox” doesn’t match any binding so it will be discarded.

Summary:

RabbitMQ is a flexible messaging solution and therefore is preferred choice for enterprise-level message broker service. Main features of RabbitMQ includes Reliability, Highly Available Queues, Many Clients, Clustering. If you want to distribute messages to different clients based on different rules, RabbitMQ would be the best choice.

For more details:

https://www.rabbitmq.com/getstarted.html