Implementation of the Microservices Communication with RabbitMQ
Below is the implementation of the Microservices Communication with RabbitMQ.
Set up the RabbitMQ
We can download RabbitMQ using this link after that, install and run RabbitMQ locally on the computer system.
Run the RabbitMQ:
rabbitmq-plugins.bat enable rabbitmq_management
Refer the below cmd plugins:
Once the above command is run, RabbitMQ will be running on the local system at port number 15672. The default username and password are “guest.”
Create the Producer-service
Below are the steps to create the producer service.
Step 1: Create a new Spring Boot project using Spring Initializr, and include the following dependencies:
- Spring Web
- Spring for RabbitMQ
- Lombok
Once the project is created, the file structure will resemble the image below.
Step 2:
Open the application.properties
file and add the RabbitMQ connection properties to the project.
spring.application.name=producer-service
# RabbitMQ Config
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.queue=my-queue
spring.rabbitmq.exchange=my-exchange
spring.rabbitmq.routingkey=my-routingkey
spring.main.allow-bean-definition-overriding=true
Step 3: Create theMessage class
We’ll create the model class for the message entity of the producer service.
Go to src > org.example.produceservice> model > Message and put the below code.
package org.example.producerservice.model;
import lombok.Data;
@Data
public class Message {
private String content;
private String sender;
public Message() {
}
public Message(String content, String sender) {
this.content = content;
this.sender = sender;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
@Override
public String toString() {
return "Message{" +
"content='" + content + '\'' +
", sender='" + sender + '\'' +
'}';
}
}
Step 4: Create the RabbitMQ Configuration class
We’ll create the configuration class to configure RabbitMQ.
Go to src > org.example.produceservice> config > RabbitMQ and put the below code.
package org.example.producerservice.config;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
@Value("${spring.rabbitmq.queue}")
private String queueName;
@Value("${spring.rabbitmq.exchange}")
private String exchange;
@Bean
public Queue queue() {
return new Queue(queueName, false);
}
@Bean
public TopicExchange exchange() {
return new TopicExchange(exchange);
}
@Bean
public Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(queueName);
}
@Bean
public MessageConverter jsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
@Bean
public AmqpTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(jsonMessageConverter());
return rabbitTemplate;
}
}
Step 5: Create the Message Controller class
We’ll create the controller class to send messages to the consumer service.
Go to src > org.example.produceservice> controller > MessageController and put the below code.
package org.example.producerservice.controller;
import org.example.producerservice.model.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class MessageController {
@Autowired
private RabbitTemplate rabbitTemplate;
@Value("${spring.rabbitmq.exchange}")
private String exchange;
@Value("${spring.rabbitmq.routingkey}")
private String routingKey;
@PostMapping("/send")
public String sendMessage(@RequestBody Map<String, String> messageBody) {
String content = messageBody.get("content");
String sender = messageBody.get("sender");
Message message = new Message(content, sender);
rabbitTemplate.convertAndSend(exchange, routingKey, message);
return "Message sent successfully!";
}
}
Step 6: Open the Main Class and insert the following code.
Go to src > org.example.produceservice > ProduceServiceApplication and put the below code.
package org.example.producerservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProducerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProducerServiceApplication.class, args);
}
}
Step 7: Run the application
Once we run the application, then the project will run at port 8080.
Create the Consumer Service
Below are the steps to create the consumer service.
Step 1: Create the Spring Boot Project
Create a new Spring Boot project using Spring Initializr, and include the following dependencies:
- Spring Web
- Spring for RabbitMQ
- Lombok
- Spring Devtools
Once the project is created, the file structure will resemble the image below.
Step 2: Configure the RabbitMQ Connection
Open the application.properties
file and add the RabbitMQ connection properties to the project.
spring.application.name=consumer-service
server.port=8081
# RabbitMQ Config
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.queue=my-queue
spring.rabbitmq.exchange=my-exchange
spring.rabbitmq.routingkey=my-routingkey
Step 3: Create the RabbitMQ Configuration class
We’ll create the configuration class to configure RabbitMQ.
Go to src > org.example.consumerservice> config > RabbitMQ and put the below code.
package org.example.consumerservice.config;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
@Value("${spring.rabbitmq.queue}")
private String queueName;
@Bean
public Queue queue() {
return new Queue(queueName, false);
}
@Bean
public MessageConverter jsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(messageConverter);
return factory;
}
}
Step 4: Create the Listener class
We will create the Listener class to configure RabbitMQ.
Go to src > org.example.consumerservice> listener > MessageListener and put the below code.
package org.example.consumerservice.listener;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class MessageListener {
@RabbitListener(queues = "${spring.rabbitmq.queue}")
public void receiveMessage(Message message) {
System.out.println("Received message: " + message);
// Process the received message
}
}
Step 5: Open the Main class and insert the following code.
Go to src > org.example.consumerservice > ConsumerServiceApplication and put the below code.
package org.example.consumerservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ConsumerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerServiceApplication.class, args);
}
}
Step 6: Run the application
Once we run the application, the project will run on port 8081. We can observe the messages being sent and received in the console.
Endpoint API:
POST http://localhost:8080/send
JSON Body:
{
"content": "Hello RabbitMQ",
"sender:" : "producer-service:
}
Output:
Consumer-service receive the message:
This example demonstrates setting up a producer service that sends messages to RabbitMQ and a consumer service that listens for messages from RabbitMQ.
Microservices Communication with RabbitMQ
Microservices are popular because they are flexible and can handle a lot. But getting them to talk to each other smoothly is a big challenge. RabbitMQ helps with that. It’s like a go-between, making sure different services can chat without any problems. In this article, we’ll see how RabbitMQ makes it easy for microservices to communicate in a big system.
Think of RabbitMQ as a helpful messenger. It follows some rules to make sure messages get from one service to another. It sits in the middle, helping out the services that send messages (producers) and the ones that get them (consumers). RabbitMQ has three main parts: Exchanges, Queues, and Bindings. They work together to make sure messages go where they’re supposed to without any issues.
Key Terminologies:
- Message Broker: A middleman that manages messages between applications.
- Message Queue: A temporary storage where messages wait for processing.
- Exchange: Routes messages from producers to queues based on predefined rules.
- Queue: Stores messages until they’re consumed by consumers.
- Binding: Defines how messages are routed from exchanges to queues.
- Producer: Generates and sends messages to RabbitMQ.
- Consumer: Receives and processes messages from RabbitMQ.
- Routing Key: Determines which queues receive messages based on exchange rules.
- AMQP: A messaging protocol defining message exchange formats and rules.
- Dead Letter Exchange (DLX): Receives undeliverable messages from queues.
- Publisher-Subscriber Pattern: Publishers send messages to an exchange, and subscribers receive them from bound queues.
- Remote Procedure Call (RPC): Clients send requests to servers and wait for responses.