Today we will be talking about RabbitMQ. We will go through brief understanding about RabbitMQ, different concept associated with it and will do some examples in next post.
Messaging Queue Overview
Before we dive into RabbitMQ, let’s get some understanding around Messaging Queue. Message queue acts as intermediary platform where different applications can send and receive message.
It is the place where queue is defined. Queue is like a collection of objects where message/data is stored and retrieved on FIFO(First In First Out) basis. A message can contain any bit of information from simple text to containing some valuable information like process or task related. This message resides on queue until the message is pulled off queue by some application.
It decouples applications where multiple systems can communicate with each other asynchronously. A message queue comprised of producer, broker and consumer. Producer is the applications that creates and sends message to the broker. Broker which is also short term storage for message sends the message to consumer or the application that is subscribed to the message. Once message is retrieved by consumer, message is removed from broker. One more advantage among millions is it is easy to scale process using messaging queue.
What is RabbitMQ?
RabbitMQ is a messaging queueing software also know as message broker that allows asynchronous communication between two systems. RabbitMQ stores message and then transfer messages to applications using several protocols that it supports like AMQP, STOMP, MQTT and HTTP. It originally implements the Advance message Queuing Protocol (AMQP).
AMQP protocol was designed following certain characteristic like security, reliability and interoperability. AMQP supports authentication, authorization, LDAP via plugins which secures the application. With reliability features, there is confirmation with message being delivered to broker from producer and to consumer from broker. It grantees that message will be delivered and processed by consumer.
Message queue holds down the information until the application/servers are ready to consume or work on it. It does not let application(consumer) to be forced and perform resource intensive operation degrading the performance of the application. Hence applications can wait for their task to be completed and then ask message queue to send them rest of the information they want.
All the operations run parallel. Producer is producing message, sending it to message broker and consumer is taking off message from the queue. The softwares are working independently with low coupling.
Due to this micro-service concept, applications can be in any language like java, node, python and so on. The applications can consume message agnostic of languages with message broker.
RabbitMQ Examples:
A messaging service acts a a middle layer in enterprise environment. It reduce loads and performance of applications by delegating task to some other service.
Let’s take a scenario that make sense. Amazon has different multiple microservice. When a user adds item to cart and check out, there are multiple actions that should propagate with this action. Since, user bought an item, there would be one less item in the collection and that should be updated in the warehouse service. Along with it, once the user checks out, system should let delivery service know about the order so that they can deliver.
Similarly, there can be email service to let user know about their order through email. As you can see there are multiple service interconnected, we do not want to send message to all the service without knowing their capacity as it will slow down the performance. There comes RabbitMQ to rescue which will hold on the message until they retrieve the messages.
Couple of core terminology that we need to keep in mind is publisher(which is Cart service in our example), consumer(can be any of the service consuming the message) and message broker which is RabbitMQ.
Exchanges
Producer does not send message to queue directly rather send it to an exchanges which is responsible to routing message to appropriate queue based on binding or routing keys. This exchange will determine which queue will get which message and based on that consumer can connect to the queue and take off messages. When producer sends message to queue, the exchange type must be specified along with different message attributes like binding, routing keys. Routing key is like address for the messages.
Types of Exchanges:
Direct Exchange
This exchange routes messages to queue based on message routing key. Producer before sending message to exchange adds a routing key in message header. Exchange then matches routing key with all the queues binding key and routes the message based on matching.
Routing key is a message attribute added to the message header by the producer. Routing key can also be taken as address to decide the routing of the message by exchange. Binding key has to match exactly to that of routing key for message to be delivered to the queue.
Topic Exchange
This exchange does some kind of matching in the pattern of routing key while sending the message to specific queues. It is based on wildcard matches between routing key and the routing pattern, specified by queue binding. Messages can be set to multiple queues based on the routing key.
The routing key is a list of words separated by a period. The routing pattern can contain an asterisk (*) to match a pattern like fullstack.*.*.coder.*. A pod symbol (‘#’) can also be used based on need which indicates a match of zero or more words in the pattern.
Fanout Exchange
As the name suggest, it routes message to all the queues. This exchange routes received message to all the queues which is not the case with direct exchange and topic exchange. Fanout ignores routing keys and the pattern matching. This is useful when multiple consumers needs to be notified based on messages.
Header Exchange
This uses message header attributes for routing rather than routing keys. If the value in message header matches to that of binding keys then the message is delivered. This is similar to that of topic exchange where multiple scenarios can be compared like the (*) in topic exchanges. There can be multiple headers attached as attributes to the message and hence to match different scenario a special argument named “x-match” is added in binding which specifies if all the headers value need to match or just any.
Installation of RabbitMQ
On Mac
Installation of RabbitMq in Mac is pretty straight forward. Homebrew which is a popular package manager for MacOS is used.The installation steps are as follows:
brew update
This command will update brew if brew is outdated. Now is the time to install rabbitmq.
brew install rabbitmq
This will install all the key dependence such as supported Erlang/OTP version. RabbitMQ server scripts and CLI tools binaries have been created under /usr/local/sbin. However they are installed under directory /usr/local/Cellar/rabbitmq/{version}/sbin. Append Path in basic or bash_profile as follows:
export PATH=$PATH:/usr/local/sbin
Add the above export to ~./.bashrc or ./bash_profile.
To start rabbitMq, run the command:
brew services start rabbitmq
This will launch the rabbitmq server in the background. The terminal log will tell that RabbitMQ has been successfully started if there is not any error.
Once RabbitMQ starts, hit the default url http://localhost:15672/. This will prompt you for username and password which is “guest”.
Just input “guest” for username and password both then you should see something like this:
To stop rabbitMQ, run the following command:
brew services stop rabbitmq
For Windows
Install:Windows:RabbitMQ: https://www.rabbitmq.com/install-windows.html
Install:Windows(manual):RabbitMQ: https://www.rabbitmq.com/install-windows-manual.html
Using Docker Image
If you have docker installed on your machine then you can simply run command:
docker run -d --name some-rabbit2 -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password rabbitmq:3-management
This will pull docker image and create an instance of container.You can also use Docker Compose.
rabbitmq:
image: rabbitmq:management
ports:
- "5672:5672"
- "15672:15672"