文章目录
4.基于RabbitMQ实现延迟队列
4.1延迟队列定义
- 延迟队列指的是存储对应的延迟消息,消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。
RabbitMQ 本身是没有延迟队列的,要实现延迟消息,一般有两种方式:
- 通过 RabbitMQ 本身队列的特性来实现,需要使用 RabbitMQ 的死信交换机(Exchange)和消息的存活时间 TTL(Time To Live)。
- 在 RabbitMQ 3.5.7 及以上的版本提供了一个插件(rabbitmq-delayed-message-exchange) 来实现延迟队列功能。同时,插件依赖 Erlang/OPT 18.0 及以上。
也就是说,AMQP 协议以及 RabbitMQ 本身没有直接支持延迟队列的功能,但是可以通过 TTL 和 DLX 模拟出延迟队列的功能。
4.2基于DLX(死信交换机)实现延迟队列
4.2.1实现思路
假如一条消息需要延迟 30 分钟执行,我们就设置这条消息的有效期为 30 分钟,同时为这条消息配置死信交换机和死信 routing_key,并且不为这个消息队列设置消费者,那么 30 分钟后,这条消息由于没有被消费者消费而进入死信队列,此时我们有一个消费者就在“蹲点”这个死信队列,消息一进入死信队列,就立马被消费了。
4.2.2主要流程
- 创建两个交换机(Exchange)和两个队列(Queue):
- 原始消息队列:将需要延迟处理的消息发送到原始消息队列。
- 死信队列:设置一个 TTL(Time-To-Live)过期时间,未在规定时间内处理的消息会成为死信消息,被发送到死信队列。
- 使用 DLX(死信交换机)关联原始消息队列和死信队列:
- 在原始消息队列声明时,设置该队列的
x-dead-letter-exchange
参数为死信交换机的名称。 - 在原始消息队列声明时,设置该队列的
x-dead-letter-routing-key
参数为死信队列的路由键。
- 在原始消息队列声明时,设置该队列的
- 消费者监听死信队列进行延迟消息处理:
- 消费者监听死信队列,一旦有死信消息到达,即可进行相应的延迟消息处理逻辑。
- 生产者发送延迟消息到原始消息队列:
- 生产者发送消息到原始消息队列,并设置消息的 TTL(即过期时间)。
- 如果消息在规定时间内未被消费者消费,则成为死信消息。
4.2.3实战
(1)创建两个消息队列:原始消息队列、死信队列 and 为原始消息队列关联私信交换机
@Configuration
public class QueueConfig {
public static final String JAVABOY_QUEUE_NAME = "javaboy_queue_name";
public static final String JAVABOY_EXCHANGE_NAME = "javaboy_exchange_name";
public static final String JAVABOY_ROUTING_KEY = "javaboy_routing_key";
public static final String DLX_QUEUE_NAME = "dlx_queue_name";
public static final String DLX_EXCHANGE_NAME = "dlx_exchange_name";
public static final String DLX_ROUTING_KEY = "dlx_routing_key";
/**
* 死信队列
* @return
*/
@Bean
Queue dlxQueue() {
return new Queue(DLX_QUEUE_NAME, true, false, false);
}
/**
* 死信交换机
* @return
*/
@Bean
DirectExchange dlxExchange() {
return new DirectExchange(DLX_EXCHANGE_NAME, true, false);
<