一、介绍
RabbitMQ 延迟消息队列是一种可以把消息存储在队列中,但是只有在达到特定的等待时间之后才能被消费的机制。这种机制可以用于处理各种需要延迟处理的任务,例如发送邮件、推送消息等。
二、安装延迟队列
1.首先要在Docker中安装RabbitMQ
2.官网下载插件
https://www.rabbitmq.com/community-pluginshttps://www.rabbitmq.com/community-plugins
(1)选择延迟消息插件
(2)根据版本进行选择
注:RabbitMQ是什么版本的,下载的插件就得是什么版本的,得对应上
我的RabbitMQ版本为3.9.13所以下载3.9.0的插件
(3)下载完成
(4)将下载完成的文件上传到服务器
(5)进入RabbitMQ容器
docker exec -it rabbitmq /bin/bash
(6)启用插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
(7)退出容器
exit
三、SpringBoot代码实现
1.导入RabbitMQ依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.添加相关配置
我这是最基础的配置
spring:
rabbitmq:
host: #ip
port: 5672
username: guest
password: guest
3.配置延迟队列
/**
* 延迟队列
*/
@Configuration
public class DelayedQueueConfig {
/**
* 队列
*/
public static final String DELAYED_QUEUE_NAME = "delayed_queue";
/**
* 交换机
*/
public static final String DELAYED_EXCHANGE_NAME = "DELAYED_EXCHANGE";
/**
* 交换机类型
*/
public static final String DELAYED_EXCHANGE_TYPE = "x-delayed-message";
/**
* 交换机路由键
*/
public static final String DELAYED_ROUTING_KEY = "delayed";
/**
* 声明延迟队列
*/
@Bean
public Queue delayedQueue() {
return new Queue(DELAYED_QUEUE_NAME);
}
/**
* 声明延迟队列交换机
*/
@Bean
public CustomExchange delayedExchange() {
Map<String, Object> map = new HashMap<>();
map.put("x-delayed-type", "direct");
/**
* 生命自定义交换机
* 第一个参数: 交换机名称
* 第二个参数: 交换机类型
* 第三个参数: 是否需要持久化
* 第四个参数: 是否自动删除
* 第五个参数: 其他参数
*/
return new CustomExchange(DELAYED_EXCHANGE_NAME, DELAYED_EXCHANGE_TYPE, true, false, map);
}
/**
* 绑定队列和延迟交换机
*/
@Bean
public Binding delayedQueueBindingDelayedExchange(
@Qualifier("delayedQueue") Queue delayedQueue,
@Qualifier("delayedExchange") Exchange delayedExchange
) {
return BindingBuilder.bind(delayedQueue).to(delayedExchange).with(DELAYED_ROUTING_KEY).noargs();
}
}
相关解释
路由键的作用
DELSEY_ROUTING_KEY 就是你在发送消息时指定的 路由键,它决定了消息应该进入哪个队列。
交换机与队列的绑定
delayedQueue 队列与 delayedExchange 交换机通过指定的路由键("delayed")绑定在一起。换句话说,任何发送到 delayedExchange 交换机,并且路由键为 "delayed" 的消息都会进入 delayedQueue 队列。
运行项目之后的效果(交换机和延迟队列通过路由键进行关联)
4.生产者
rabbitTemplate.convertAndSend(DelayedQueueConfig.DELAYED_EXCHANGE_NAME, DelayedQueueConfig.DELAYED_ROUTING_KEY, 1234, correlationData -> {
correlationData.getMessageProperties().setDelay(10000);
return correlationData;
});
参数解释
(1)DelayedQueueConfig.DELAYED_EXCHANGE_NAME
这是发送消息的交换机(Exchange)名称。在RabbitMQ中,交换机用于将消息路由到一个或多个队列。这个参数指定了要将消息发送到哪个交换机。DELAYED_EXCHANGE_NAME 是一个常量,可能会在配置类 DelayedQueueConfig 中定义。
- 类型: String
- 作用: 指定目标交换机的名称。
(2)DelayedQueueConfig.DELAYED_ROUTING_KEY
这是消息的路由键(Routing Key)。在RabbitMQ中,路由键用于决定消息路由到哪个队列。DELAYED_ROUTING_KEY 是一个常量,表示发送消息时使用的路由键。路由键的选择通常取决于交换机类型,某些交换机(如Direct或Topic交换机)会根据路由键的值来决定消息的投递目标。
- 类型: String
- 作用: 指定消息的路由键,决定消息的目标队列。
(3)1234
这是发送的消息内容。在这个例子中,消息的内容是一个整数(1234),可以是任何类型的对象。RabbitMQ会将这个消息对象序列化为字节流,并将其发送到指定的交换机。
- 类型: Object(此例为 Integer)
- 作用: 发送到RabbitMQ的消息体。可以是任何类型的数据,RabbitMQ会将其序列化。
(4)correlationData -> { correlationData.getMessageProperties().setDelay(10000); return correlationData; }
这是一个回调函数,用于在发送消息之前修改消息的属性。它接收一个 correlationData 对象,该对象包含消息的相关信息。你可以通过这个回调来修改消息的属性,例如设置消息的延迟时间。
- 类型: MessagePostProcessor(这是一个函数式接口,允许你在消息发送前对其进行处理)
- 作用: 在消息发送前修改消息的属性。在这里,回调函数通过 correlationData.getMessageProperties().setDelay(10000) 设置消息延迟时间为10秒(10000毫秒)。这意味着消息将在10秒后才会投递到目标队列。
5.消费者
import com.rabbitmq.client.Channel;
import com.shopgoods.order.config.DelayedQueueConfig;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 延迟队列消费者
*/
@Log4j2
@Component
public class OrderVoluntarily {
@RabbitListener(queues = DelayedQueueConfig.DELAYED_QUEUE_NAME)
public void receiveDelayQueue(Integer a, Message message, Channel channel) throws IOException {
log.info("当前时间:{},取出的值为{}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),a);
}
}
6.效果