What is RabbitMQ in Spring Boot and how to use it

What is RabbitMQ in Spring Boot and how to use it

Introduction

RabbitMQ is an open source message queuing system, which implements message delivery through AMQP (Advanced Message Queuing Protocol). Spring Boot is currently a very popular Java development framework, which provides many convenient functions, including support for RabbitMQ.

In this article, we will introduce the basic concepts of RabbitMQ and how to use RabbitMQ in Spring Boot.

insert image description here

Basic concepts of RabbitMQ

Before using RabbitMQ, we need to understand some basic concepts.

message queue

Message queues are a mechanism for asynchronous communication. The message sender sends the message to the queue, and the message receiver gets the message from the queue. Through the message queue, the asynchronous delivery of messages can be realized, and the coupling between systems can be reduced.

information

A message is the data that needs to be delivered.

producer

A producer is a program that sends messages to a message queue.

consumer

A consumer is a program that obtains and processes messages from a message queue.

queue

A queue is a place where messages are stored.

switch

The exchange is used to receive the message sent by the producer and route the message to the corresponding queue.

routing key

The routing key is a string specifying which queue the message should be routed to.

to bind

Binding refers to the process of connecting queues and exchanges.

How to use RabbitMQ with Spring Boot

add dependencies

First, we need to add RabbitMQ dependency in Maven or Gradle. In Maven, we can add the following dependencies:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

In Gradle, we can add the following dependencies:

implementation 'org.springframework.boot:spring-boot-starter-amqp'

Configure RabbitMQ

In Spring Boot, we can use application.yml or application.properties files to configure RabbitMQ.

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

create producer

Here is an example of a simple RabbitMQ producer:

@Component
public class RabbitMQProducer {
    
    
    private final RabbitTemplate rabbitTemplate;

    public RabbitMQProducer(RabbitTemplate rabbitTemplate) {
    
    
        this.rabbitTemplate = rabbitTemplate;
    }

    public void send(String message) {
    
    
        rabbitTemplate.convertAndSend("myExchange", "myRoutingKey", message);
    }
}

In this example, we use the RabbitTemplate class provided by Spring AMQP to send messages. convertAndSendmethod is used to send a message to the specified exchange and routing key.

create consumer

Here is an example of a simple RabbitMQ consumer:

@Component
public class RabbitMQConsumer {
    
    
    @RabbitListener(queues = "myQueue")
    public void receive(String message) {
    
    
        System.out.println("Received message: " + message);
    }
}

In this example, we use @RabbitListenerthe annotations provided by Spring AMQP to specify which queue the consumer should listen to. When a message arrives on the queue, receivethe method will be called, and the content of the received message will be passed to the method as a parameter.

Run the example

We have now created a simple RabbitMQ application. We can create Spring Boot application in main method and inject our producer and consumer in it. Then, we can use the producer to send messages to the queue, and the consumer will receive these messages and output them to the console.

@SpringBootApplication
public class Application implements CommandLineRunner {
    
    
    private final RabbitMQProducer rabbitMQProducer;
    private final RabbitMQConsumer rabbitMQConsumer;

    public Application(RabbitMQProducer rabbitMQProducer, RabbitMQConsumer rabbitMQConsumer) {
    
    
        this.rabbitMQProducer = rabbitMQProducer;
        this.rabbitMQConsumer = rabbitMQConsumer;
    }

    public static void main(String[] args) {
    
    
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
    
    
        rabbitMQProducer.send("Hello, RabbitMQ!");
    }
}

After running the program, we can see output similar to the following on the console:

Received message: Hello, RabbitMQ!

This indicates that we have successfully sent a message to the queue and the consumer has successfully received the message.

RabbitMQ Advanced Features

In addition to basic functions, RabbitMQ also provides some advanced functions, such as:

message confirmation

When a producer sends a message, it does not know whether the message has been successfully processed. If the message is not successfully processed, the producer will keep trying to resend the message until it is successfully processed.

To solve this problem, RabbitMQ provides a message confirmation mechanism. When a producer sends a message, it can ask RabbitMQ to confirm whether the message has been successfully processed. If the message has been successfully processed, RabbitMQ will send an acknowledgment message to the producer.

@Component
public class RabbitMQProducer {
    
    
    private final RabbitTemplate rabbitTemplate;

    public RabbitMQProducer(RabbitTemplate rabbitTemplate) {
    
    
        this.rabbitTemplate = rabbitTemplate;
    }

    public void send(String message) {
    
    
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("myExchange", "myRoutingKey", message, correlationData);
    }

    @Bean
    public ConfirmCallback confirmCallback() {
    
    
        return (correlationData, ack, cause) -> {
    
    
            if (ack) {
    
    
                System.out.println("Message with correlation id " + correlationData.getId() + " has been confirmed");
            } else {
    
    
                System.out.println("Message with correlation id " + correlationData.getId() + " has been rejected: " + cause);
            }
        };
    }
}

In this example, we use the class in the producer CorrelationDatato track messages. We also created a ConfirmCallbackbean to handle message acknowledgments. When the message is successfully processed, confirmCallbackthe method will be called and output a confirmation message. When the message is rejected, confirmCallbackthe method will also be called and output a rejection message.

message persistence

By default, RabbitMQ does not persist messages to disk. If RabbitMQ doesn't deliver messages to consumers before it crashes, those messages will be lost.

To solve this problem, we can mark the message as persistent. This way, even if RabbitMQ crashes, messages are saved to disk and resent to consumers after RabbitMQ restarts.

@Component
public class RabbitMQProducer {
    
    
    private final RabbitTemplate rabbitTemplate;

    public RabbitMQProducer(RabbitTemplate rabbitTemplate) {
    
    
        this.rabbitTemplate = rabbitTemplate;
    }

    public void send(String message) {
    
    
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
        Message messageObject = new Message(message.getBytes(), messageProperties);
        rabbitTemplate.send("myExchange", "myRoutingKey", messageObject);
    }
}

In this example, we use the class in the producer MessagePropertiesto set the persistence property of the message. We also use MessageDeliveryMode.PERSISTENTthe enumeration value to mark the message as persistent.

Message TTL

Message TTL (Time To Live) refers to the time when a message is stored in the queue. If the message is not consumed by the consumer within the specified time, it will be automatically removed from the queue.

@Component
public class RabbitMQProducer {
    
    
    private final RabbitTemplate rabbitTemplate;

    public RabbitMQProducer(RabbitTemplate rabbitTemplate) {
    
    
        this.rabbitTemplate = rabbitTemplate;
    }

    public void send(String message) {
    
    
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setExpiration("5000"); // 5 seconds
        Message messageObject = new Message(message.getBytes(), messageProperties);
        rabbitTemplate.send("myExchange", "myRoutingKey", messageObject);
    }
}

In this example, we use MessagePropertiesthe class in the producer to set the TTL property of the message. We messageProperties.setExpiration("5000")set to 5000 milliseconds, which means messages are stored in the queue for a maximum of 5 seconds.

dead letter queue

A dead letter queue means that when a message is rejected or expires, it will be rerouted to another queue. This queue is called a dead letter queue.

@Configuration
public class RabbitMQConfig {
    
    
    @Bean
    public Queue myQueue() {
    
    
        return QueueBuilder.durable("myQueue")
                .withArgument("x-dead-letter-exchange", "myDeadLetterExchange")
                .withArgument("x-dead-letter-routing-key", "myDeadLetterRoutingKey")
                .build();
    }

    @Bean
    public Queue myDeadLetterQueue() {
    
    
        return QueueBuilder.durable("myDeadLetterQueue").build();
    }

    @Bean
    public Exchange myExchange() {
    
    
        return ExchangeBuilder.directExchange("myExchange").durable(true).build();
    }

    @Bean
    public Exchange myDeadLetterExchange() {
    
    
        return ExchangeBuilder.directExchange("myDeadLetterExchange").durable(true).build();
    }

    @Bean
    public Binding binding() {
    
    
        return BindingBuilder.bind(myQueue()).to(myExchange()).with("myRoutingKey").noargs();
    }

    @Bean
    public Binding deadLetterBinding() {
    
    
        return BindingBuilder.bind(myDeadLetterQueue()).to(myDeadLetterExchange()).with("myDeadLetterRoutingKey").noargs();
    }
}

In this example, we create a myQueuequeue named and use withArgumentthe method to specify its dead-letter exchange and routing key. We also created a myDeadLetterQueuequeue called and bound it to myDeadLetterExchangean exchange called . Finally, we create the binding, which myQueuebinds the queue to myExchangethe exchange.

When a message myQueueis rejected or expires in the , it will be re-routed to myDeadLetterExchangethe exchange, which will route it to myDeadLetterQueuethe queue.

Summarize

This article introduces the basic concepts of RabbitMQ and how to use RabbitMQ in Spring Boot. We also introduced some advanced features of RabbitMQ, including message confirmation, message persistence, message TTL and dead letter queue. By studying this article, you should have enough knowledge to start using RabbitMQ with Spring Boot.

Guess you like

Origin blog.csdn.net/2302_77835532/article/details/131487901