Well, let’s say we have a distributed system and services. A simple way to enable communication between those services is to make them call each other directly. This is called RPC-style communication. RPC stands for remote procedure call. We know the address (URL or IP Address) of the service we want to communicate with and we directly call them. This is done synchronously.
What we can also do is to create a message-based-system. In this system, services are decoupled from each other, there is a mediator in between called a message broker that receives the messages from the publisher or producer and forward it to the queues for consumers to pull from. In this system, a producer no longer needs to know the address of the consumer(s), the only thing it needs to know is the address of the message broker. Decoupling is restored!
That’s where the RabbitMQ comes to the stage! RabbitMQ is a free and open source message broker. There are also other message brokers in the market that examples include ActiveMQ, Kafka, AWS SQS etc.
As anything else that travels through a network, messages between those services follows protocols. RabbitMQ uses many of them, the most commonly used of which is AMQP (Advanced Message Queueing Protocol). As it is stated in the website,
The Advanced Message Queuing Protocol (AMQP) is an open standard for passing business messages between applications or organizations.
It is a binary protocol which means that the messages are sent in the binary format.
Now let’s have a look at how message brokers actually operate:
Now if we have a look at the image above, a producer creates a message and publishes it, when this message comes to the broker, it’s not directly forwarded to a consumer, not even to a queue. First it comes to exchange. Depending on the exchange type, it is forwarded (or not) to one or more queues and a consumer pulls that message. What is not shown in the above image is the consumer sends an acknowledgement message back to the broker so that message can be deleted from the queue.
There are four types of exchanges that we can publish our messages to, but before explaining what these are, there is one more concept I need to tell you about: Routing key.
Routing key is one of the attributes we add to the header of the message to hint the broker about who we want our messages to arrive at. Now let’s have a look at the exchange types:
- Direct: Direct exchange is like sending an email. It is best for simple scenarios. You can think of it like sending an email. You type your routing key to the To section of your email and those consumers who binds to that routing key will get those messages.
- Fanout: Fanout is like broadcasting. Routing key is ignored and messages is forwarded to all queues bounded to it.
- Topic: You can think of topic exchange is actually a superset of direct exchange. Unlike direct exchange, instead of writing our routing key explicitly, we use a regular expression-like routing key. (For example: key.* for any keys starting with “key.”) It is great for background tasks and to publish events happening in the service.
- Headers: This exchange type looks at the header attributes in the message instead of the routing key to decide where to route the messages.
You can run RabbitMQ after installing it to your machine or a docker image is also available to start working. You can look at here for options.
I’ll have another post on RabbitMQ to showcase it using in a SpringBoot Application. But this is what basically what RabbitMQ is.