RabbitMQ with Java and Spring, asynchronous communication between microservices
By: Pedro Luiz
Tags: Java, Messaging, Rabbitmq, Microservices, Spring

In this article we will go over RabbitMQ practical implementation and try to look to the theoretical concepts meanwhile. We will be covering only windows installations with details, but the rest of the article work the same for any OS.

Installing RabbitMQ on Windows

Navigate to RabbitMQ.

2. Click on Using the official installer.

3. Click on Erlang/OTP Version Tree, rabbit needs Erlang installed to run properly as a service on windows, so we will install it before rabbit.

4. You can click on win64 or win32 depending on your needs. Follow the instructions and Erlang will be installed.

5. Navigate back to the page we were on step 2 and download rabbit..exe, by clicking on the installer with the indicated version.

6. After following all the steps and RabbitMQ is successfully installed, we need to verify is Rabbit is running as a service on windows. Search for “Services” on windows search bar, find RabbitMQ in the list, double click it, if it shows “Service Status: Running” or something like that, it was installed properly.

Let’s get started.

Setting up plugins to run rabbitmq broker locally

Navigate to the following folders:

C: -> Program Files -> RabbitMQ Server -> rabbitmq_server-versionYouInstalled -> sbin

Now open that folder on cmd. There are a bunch of .bat files on this folder, they will be enabling the plugins which we need. Run rabbitmq-plugins.bat enable rabbitmq_management (if later you want to disable it, just run it with disable instead). Go to your browser and go to: localhost:15672. I hope you see a page that looks like this:

We will log in to RabbitMQ user interface. By default rabbit uses “guest” as username and password, so go ahead and log in with them.

Go ahead, take a look at the UI. As I said earlier, it isn’t the purpose of this article to detail this interface, I only went this far without coding because we will be using it while we develop our projects.

You can create your projects in spring io, or simply just clone mine to follow along at my GitHub.

Producer MircroService Project

Consumer Microservice Project

Messaging with any messaging tool is all about, publishing a message to someplace and then a someone subscribes on it.

What is message and why we need it ?

SOAP protocol has message, header and body

asynchronous, different for a synchronous http request

example:

customers messages, orders coming in a huge load

we can process them one by one

we use advanced messaging to encapsulate any kind of information

queues, topics, channels, exchanges, depends on the protocol definition

How does this message goes from the producer to consumer ?

Exchanges

first to receive the message

routes a message to one or more queue

routing algorithms depends on exchange types and “bidings”

“biding” is nothing more than a configuration to bind exchanges to queues

types:

direct = empty string and amq.direct

fanout = amq.fanout

topic = amq.topic (user purchased, for example)

headers = amq.match and amq.headers

Queues

messages arrive from exchanges to queues

where messages go before reaching a subscriber

properties:

name: name of the queue

durable: either to persist to disk or not

exclusive: delete the queue if not used anymore

auto-delete: delete the queue when consumer unsubscribes

Bidings

rules that exchanges use to route messages to queues

from exchange E to queue K, K has to be bound to E

may have an optional routing key attribute used by some exchange types

routing_key acts like a filter

imagine something like:

queue is a destination city

exchanges are like the airport of this city

bidings are the routes to arrive from the airport to the city

there can be zero or many routes possible to reach it

Setting up project to work with rabbit

Rabbit template used methods to send any kind of data, we can send a simple string

If you are using IntelliJ, I highly recommend you to CTRL + CLICK in the .converAndSend() RabbitTemplate method to get to know it a little more.

Run your application, and you will see in the logs something like this:

Go to localhost:15672 -> Exchanges -> (AMQP default). Remember that the once a message is published, it gets to a Exchange, but we didn’t configure/said to rabbit which exchange to send the message we publish. When it happens, it goes to the default exchange.

When a message is published to a exchange, this graphic show the activity, if you don’t see it, run your application again, because maybe you didn’t make it fast enough to see it happening.

If we scroll down a little in the Exchanges section we can see a very interesting definition to the Default Exchange:

Let’s not focus on what happened with this message or where did it go, let’s dive into this in a real example.

Go to Exchange, “Add a new exchange” follow this and hit “Add exchange”

2. Go to Queue, “Add a new queue”, follow this and hit “Add queue”

3. In Queues, go to the Queues list and find the “MediumQueue” which we just created, click it. Scroll down to the Bindings section and now we will bind the MediumExchange to our MediumQueue. Follow it and hit “Bind”.

You should see something like:

Run the application again, go to the MediumExchange, we will be able to see the activity of the message being published. Then go to the MediumQueue, scroll down to “Get Messages”, hit “Get Message(s)” and you will see the message in the Queue.

Now what would be great is, don’t configure which exchange, routing_key and queue to use, manually. So we will do it all on code.

Go to the Consumer Microservice

Create the following file, and set it up as follows:

Ok, we are planning on printing the message, but how we tell the consumer microservice, which queue to consume ?

So we need to configure this in the project:

Run the application again, you will see that the “SecondMediumQueue” was created by the consumer microservice.

Now, we are going to create a Exchange, and bind it to the “SecondMediumEQueue” with a routing_key named “topic”:

Now we can verify that the exchange and queue were created, as well as the routing key that gathers them:

If we go to out Producer Microservice, and as before publish a message to a queue, but this time, using the exchange, routing_key and queue which we just created from the consumer, we can see the microservices communicating.

Run the application and as long as the consumer microservice is still running, you should see the message being consumed. Something like this:

The last thing I want you to do is, try to get the message in the “SecondMediumQueue”, you will see it is no longer there.

Thank you for reading this article, there are several topics wich weren’t covered deeply in this article, of course.

The main idea here was to make a project to implement two microservices communicating through RabbitMQ, so you can implement this solution inside a much more complex system. I intend to make another article covering exchanges types, such as topics, fanout , headers and much more…

Feel free to contribute to these projects making a pull request, suggesting or implementing new features, or reviewing something that I coded.

Project on Github:

Find me on: Github profile | Linkedin