Organizations today have achieved great heights with microservice-based architectures in modern applications. Spring Boot is one such Open-source framework that allows you to create microservice applications effortlessly. With Spring, you can add several components like Message Broker, Databases, GUI, Configuration Files, Repositories, Containers, API Gateway, and more services. To provide seamless functioning of these applications, communication between such services is essential. You can leverage RabbitMQ Message Broker for obtaining efficient communication between microservice-based applications. 

In this article, you will learn to set up a Spring Message Queue using RabbitMQ.

Prerequisites

Fundamental understanding of microservices

What is RabbitMQ?

spring message queue: rabbit mq logo

Developed in 2007, RabbitMQ is one of the most popular, lightweight, Open-source Messaging Servers used worldwide by organizations. It is a message broker that accepts and forwards messages among applications. RabbitMQ consists of queues defined for connecting to applications for transferring messages. These messages can be information about a process or task, text messages, and more. Such messages are stored temporarily in RabbitMQ until the applications receive them. Therefore, RabbitMQ enables users to be part of larger applications using devices or data. It is also called Queue Manager.

RabbitMQ supports several messaging protocols like AMQP (Advanced Message Queueing Protocol), STOMP (Simple Text Oriented Messaging Protocol),  MQTT (The standard for IoT Messaging), and more. It also executes on multiple operating systems and provides developer tools for popular languages.

Key Features of RabbitMQ

  • Distributed Deployment: Users can deploy RabbitMQ as clusters for high availability and throughput. These clusters are located across multiple availability zones and regions to be available quickly.
  • Asynchronous Messaging: RabbitMQ supports multiple messaging protocols, message queueing, delivery acknowledgment, and exchange boxes.
  • Lightweight: RabbitMQ is lightweight, as the systems require less than 40 MB to run the core application and plugins. But adding messages to the queue will increase memory usage.
  • Tools and Plugins: RabbitMQ offers a variety of tools and plugins for continuous integration, operational metrics, and integration to other enterprise systems.
  • Flexibility in Controlling Messaging Trade-offs: RabbitMQ enables you to control the trade-offs between message throughput and performance. All the messages in the queue can specify where they should be saved to a disc before delivery. Queue in a cluster can span multiple servers, ensuring that no messages are lost in the event of a server failure.
Simplify ETL Using Hevo’s No-Code Data Pipeline

Hevo Data, a Fully-managed Data Pipeline platform, can help you automate, simplify & enrich your data replication process in a few clicks. With Hevo’s wide variety of connectors and blazing-fast Data Pipelines, you can extract & load data from 150+ Data Sources straight into Data Warehouses, or any Databases. To further streamline and prepare your data for analysis, you can process and enrich raw granular data using Hevo’s robust & built-in Transformation Layer without writing a single line of code!

Check out what makes Hevo amazing:

  • Scalable Infrastructure: Hevo has in-built integrations for 150 sources that can help you scale your data infrastructure as required.
  • Fully Managed: It requires no management and maintenance as Hevo is a fully automated platform.
  • Data Transformation: It provides a simple interface to perfect, modify, and enrich the data you want to transfer.
  • Real-Time: Hevo offers real-time data migration. So, your data is always ready for analysis.
  • Schema Management: Hevo can automatically detect the schema of the incoming data and map it to the destination schema.
Get Started with Hevo for Free

Basic Concepts of RabbitMQ

The following are some of the basic terminologies associated with RabbitMQ:

  • Producer (Publisher): It is the one who sends messages to the queue based on the queue name.
  • Queue: It is a sequential data structure that acts as a medium through which messages are transferred and stored.
  • Consumer (Subscriber): It is the one who subscribes to and receives messages from the broker and uses those messages for other operations.
  • Exchange: It is an entry point for the broker because it takes messages from the publisher and routes the messages to appropriate queues.
  • Broker: It is a message broker that provides storage for data produced. The data produced should be consumed or received by another application connected to the broker.

How to Build a Spring Message Queue using RabbitMQ?

AMQP is a message protocol that deals with publishers and consumers. It is used for passing messages between organizations or applications. You will set up the RabbitMQ AMQP server that publishes and subscribes to messages along with the Spring Boot application. 

You will build an application that publishes a message using Spring’s AMQP’s RabbitTemplate and subscribes to the message on POJO by MessageListenerAdapter.

Prerequisites

  • A text editor or IDE
  • JDK 11 or later
  • Gradle 4+ or Maven 3.2+

Step 1: Set up the RabbitMQ Broker

Before building your messaging application for the Spring Message Queue, you must set up a RabbitMQ server to handle receiving and sending messages. To set up the RabbitMQ message broker, follow the below steps.

  • Download the RabbitMQ server.
  • To unpack the server and launch the server with default settings, run the below command in a terminal.
rabbitmq-server

Output:

spring message queue: rabbit mq broker install
Image credit: Spring

The Docker Compose can also be used to launch a RabbitMQ Server.

Step 2: Starting with Spring Initialzr

Spring Initialzr is a web-based tool that generates the Spring Boot Project structure for the Spring Message Queue.

Follow the below steps to initialize Spring.

  • Go to Spring Initialzr; it will pull all the dependencies required for an application.
  • Choose Gradle or Maven and then the language you want to use. (This article uses Java language.) 
  • Click on Dependencies and select Spring for RabbitMQ to create the Spring Message queue.
  • Click on Generate.
  • Download the resulting zip file that is an archive of a web application configured with your choices.

Step 3: Create a RabbitMQ Message Receiver

You must create a receiver that responds to published messages for any message-based application of the Spring Message Queue. Therefore, include the below code in:

src/main/java/com.example.messagingrabbitmq/Receiver.java.

package com.example.messagingrabbitmq;

import java.util.concurrent.CountDownLatch;
import org.springframework.stereotype.Component;

@Component
public class Receiver {

  private CountDownLatch latch = new CountDownLatch(1);

  public void receiveMessage(String message) {
    System.out.println("Received <" + message + ">");
    latch.countDown();
  }

  public CountDownLatch getLatch() {
    return latch;
  }

}

The receiver for the Spring Message Queue is a POJO, which defines a method for receiving messages.

Step 4: Register the Listener and Send a Message

Spring’s AMQP RabbitTemplate provides all the functionalities needed to send and receive messages for Spring Message Queue with RabbitMQ. Although, you need to:

  • Configure a message listener container.
  • Declare the Queue and Exchange. Then declare the binding between Queue and Exchange.
  • Configure a component for sending some messages to test the listener.

Spring Boot will automatically create a connection factory and a RabbitMQ, which will reduce the amount of code. A connection factory encapsulates the set of configuration parameters that the administrator defines.
You can use RabbitTemplate to send messages. You need to register a Receiver for Spring Message queue with the message listener container to receive messages. The connection factory drives Receiver and RabbitTemplate by connecting them to the RabbitMQ server. Therefore, include the below code:

src/main/java/com.example.messagingrabbitmq/MessagingRabbitApplication.java

To connect Receiver and RabbitTemplate to the RabbitMQ server for the Spring Message queue:

package com.example.messagingrabbitmq;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class MessagingRabbitmqApplication {

  static final String topicExchangeName = "spring-boot-exchange";

  static final String queueName = "spring-boot";

  @Bean
  Queue queue() {
    return new Queue(queueName, false);
  }

  @Bean
  TopicExchange exchange() {
    return new TopicExchange(topicExchangeName);
  }

  @Bean
  Binding binding(Queue queue, TopicExchange exchange) {
    return BindingBuilder.bind(queue).to(exchange).with("foo.bar.#");
  }

  @Bean
  SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,
      MessageListenerAdapter listenerAdapter) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(connectionFactory);
    container.setQueueNames(queueName);
    container.setMessageListener(listenerAdapter);
    return container;
  }

  @Bean
  MessageListenerAdapter listenerAdapter(Receiver receiver) {
    return new MessageListenerAdapter(receiver, "receiveMessage");
  }

  public static void main(String[] args) throws InterruptedException {
    SpringApplication.run(MessagingRabbitmqApplication.class, args).close();
  }

}

From above, 

@SpringBootApplication: It is a convenience annotation that adds all of the following:

  1. @Configuration: It is used to tag the class as a source of bean definitions for the application context. Beans are the objects that construct the backbone of your Spring application. They are managed by Spring IoC Container.
  2. @EnableAutoConfiguration: It tells the Spring Boot to start adding beans based on classpath settings, other beans, and other property settings. 

@ComponentScan: It tells Spring to look for other components, configurations, and services in the com/example package.

The main() method uses Spring Boot’s StringApplication.run() method to launch an application.

The bean that is defined in the listenerAdapter() method is registered as a Message Listener in the container defined in container(). It also listens for messages on the Spring-boot queue. Since the receiver class is a POJO, it needs to be wrapped in MessageListenerAdapter

The message listener container and receiver beans are needed for listening to the messages. You also need a RabbitMQ template to send a message.

  • queue(): It creates an AMQP queue.
  • exchange(): It creates a topic exchange.
  • binding(): It binds queues and exchanges together. It defines the behavior that occurs when RabbitTemplate publishes to an exchange.

In this article, you have used topic exchange and the queue with routing key of foo.bar.#, meaning any messages sent with a routing key that begins with foo.bar is routed to the queue.

Step 5: Send a Test Message

The test messages for verifying the Spring Message queue are sent by a CommandLineRunner. CommandLineRunner waits for the latch in the receiver and closes the application context. Therefore, include the below code to send a test message for the Spring Message queue:

src/main/java/com.example.messagingrabbitmq/Runner.java
package com.example.messagingrabbitmq;

import java.util.concurrent.TimeUnit;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class Runner implements CommandLineRunner {

  private final RabbitTemplate rabbitTemplate;
  private final Receiver receiver;

  public Runner(Receiver receiver, RabbitTemplate rabbitTemplate) {
    this.receiver = receiver;
    this.rabbitTemplate = rabbitTemplate;
  }

  @Override
  public void run(String... args) throws Exception {
    System.out.println("Sending message...");
    rabbitTemplate.convertAndSend(MessagingRabbitmqApplication.topicExchangeName, "foo.bar.baz", "Hello from RabbitMQ!");
    receiver.getLatch().await(10000, TimeUnit.MILLISECONDS);
  }
}

Step 6: Run the Application

The main() method starts the application by starting the message listener container, which starts listening for the messages in the Spring Message queue. There is a Runner Bean that runs automatically after starting the Message Listener container for the Spring Message queue. It retrieves the RabbitTemplate from the application context and sends a ‘Hello from RabbitMQ!’ message on the spring-boot queue. Runner Bean then closes the Spring application context. Therefore, the application ends.

Step 7: Build an Executable JAR

You can run the application for the Spring Message Queue using the command line with Gradle or Maven. A single executable JAR can also be built, which contains all the necessary dependencies, classes, and resources and execute them.

If you want to use Gradle, run the application using ./gradlew bootRun. Instead, you can build the JAR file with ./gradlew build and then run the JAR file using the below command.

java -jar build/libs/gs-messaging-rabbitmq-0.1.0.jar

If you want to use Maven, run the application for Spring Message queue using ./mvnw spring-boot:run. Instead, you can build the JAR file with ./mvnw clean package build and then run the JAR file using the below command.

java -jar target/gs-messaging-rabbitmq-0.1.0.jar

Output:

Therefore, you have developed a simple publish-and-subscribe application for the Spring Message queue using RabbitMQ.

Conclusion

In this article, you learned about setting up a simple publish-subscribe application for the Spring Message Queue using RabbitMQ. This article also focuses on the features and basic concepts of RabbitMQ. Organizations use RabbitMQ to develop and manage scalable applications. Organizations like JPMorgan Chase, Doordash, FireEye, Radancy, Salesforce, Citi, and more currently use RabbitMQ for their Microservices architecture. Explore Spring Boot’s messaging queue capabilities for efficient communication between components in your applications.

There are various Data Sources that organizations leverage to capture a variety of valuable data points. But, transferring data from these sources into a Data Warehouse for a holistic analysis is a hectic task. It requires you to code and maintains complex functions that can help achieve a smooth flow of data. An Automated Data Pipeline helps in solving this issue and this is where Hevo comes into the picture. Hevo Data is a No-code Data Pipeline and has awesome 150+ pre-built Integrations that you can choose from. Try a 14-day free trial and experience the feature-rich Hevo suite firsthand. Also, check out our unbeatable pricing to choose the best plan for your organization.

FAQs

1. What is a message queue for dummies?

A message queue refers to a program that stores messages in a temporary place between applications that will ensure the messages are processed in order without data loss. Communication management and smooth data flow were guaranteed by the queue.

2. Can we use Kafka as message queue?

Kafka can be used as a message queue. It allows for high-throughput messaging with its publish-subscribe model and supports message storage and delivery for various use cases.

3. Do message queues use HTTP?

They do not necessarily use HTTP, though some systems like Apache Kafka or RabbitMQ can make use of HTTP-based protocols, like REST APIs, while most message queues have their own protocol optimized for message delivery and processing-AMQP, MQTT, or TCP.

Arsalan Mohammed
Research Analyst, Hevo Data

Arsalan is a research analyst at Hevo and a data science enthusiast with over two years of experience in the field. He completed his B.tech in computer science with a specialization in Artificial Intelligence and finds joy in sharing the knowledge acquired with data practitioners. His interest in data analysis and architecture drives him to write nearly a hundred articles on various topics related to the data industry.