【学习笔记】RabbitMQ04:延迟队列的原理以及实现代码

本文介绍了如何在RabbitMQ中使用延迟队列处理延迟任务,包括定时任务、被动取消、JDK延迟队列以及利用rabbitmq_delayed_message_exchange插件的实例和解决不同消息延迟时间的问题。

参考资料

七、延迟队列

7.1 什么是延迟队列

正常的MQ应用场景中,我们希望消息可以快速稳定的传递。但是有一些场景中,希望在指定的延迟后再消费信息,比如订单支付场景(订单15部分内未支付则关闭订单)。

这类实现延迟任务的场景,就可以采用延迟队列来实现。

以下介绍一下其他的一些方法。

7.2 延迟队列的解决方案

7.2.1 定时任务

每隔n秒扫描一次数据库,查询数据库装为过期的订单进行处理。

实现方式

spring schedule、quartz、xxljob等

优点

简单,容易实现;

缺点

  1. 存在延迟(受定时器延迟时间限制
  2. 性能较差,每次扫描数据库,如果订单量交大,会给数据库造成较大压力。
7.2.2 被动取消

当用户主动查询订单时,判断订单是否超时,超时则取消

  • 优点:服务器压力小
  • 缺点:如果用户长时间不查询,则会造成统计异常;而且用户打开订单页面会变慢,严重的话会影响用户体验
7.2.3 JDK的延迟队列

DelayedQueue:无界阻塞队列,该队列只有在延迟期满后,才能从中获取元素。

优点

实现简单,任务的延迟低。

缺点

  • 服务器重启宕机,数据会丢失
  • 只适用于单机版
  • 订单量大时,可能会造成内存不足:OOM
7.2.3 采用消息中间件(rabbitMQ

RabbitMQ 本身不支持延迟队列,可以使用 TTL 结合 DLX 的方式来实现消息的延迟投递(前面提到的死信队列)。.

image-20231017141210411

把 DLX 跟某个队列绑定,到了指定时间,消息过期后,就会从 DLX 路由到这个队列,消费者可以从DLX的队列中取走消息。

7.2.3.1 适用专门优化后的死信队列实现延迟队列

在上面的mq方案中,存在两个不同的交换机,我们可以利用直连交换机的特性,将交换机优化成一个交换机,同时通过不同的routingKey指定普通队列和死信队列。

image-20231017141445269

思路解释

  1. 生产者发送消息到交换机X,并指定ttl的key
  2. 消息被交换机传递到ttl队列中(指定了消息过期时间的队列
  3. 同时,ttl队列还指定的死信交换机DLX为自身的交换机X,但是指定的routingKey为死信队列的key
  4. 这样,当消息在ttl队列中到期后,这条消息就会被传递到死信队列中,提供给消费者
7.2.3.2 ⭐️实例代码

为了便于测试,将发送和接收写在同一个服务中

配置信息

@Configuration
public class DelayExchangeConfig {
   
   
    public static String exchangeName = "order.ttl.exchange";
    public static String orderQ = "order.ttl.queue";
    public static String dlxQ = "order.dlx.queue";

    @Bean
    public DirectExchange delayedExchange(){
   
   
        return ExchangeBuilder.directExchange(exchangeName).build();
    }

    @Bean
    public Queue orderQueue(){
   
   
        // 指定该队列的过期时间和死信队列
        Map<String , Object> properties = new HashMap<>();
        properties.put("x-message-ttl" , 15000);
        properties.put("x-dead-letter-exchange" , exchangeName);
        properties.put("x-dead-letter-routing-key" , "dead-letter")
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xcong_Zhu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值