RabbitMq 实现延迟队列

欢迎转载分享,转载请注明出处。 如有问题欢迎指正 更多实时文章请关注公众号:WTF名字好难取

推荐书籍:《RabbitMQ实战指南 》朱忠华 。欢迎购买正版书籍。 想要 电子版参考的小伙伴,可以关注公众号 【WTF名字好难取】回复,【推荐书籍】,获取下载地址。

本文参考:《RabbitMQ实战指南》4.2 , 4.3 ,4.4 章节,进行实现并落地。

RabbitMq 实现延迟队列

通过 RabbitMQ 延迟队列,我们需要关注的2个知识点(这里不进行知识普及,可以通过推荐书籍,官方网址等其他方式获取基础知识

  • 消息的过期时间(TTL)
  • 死信队列

消息延迟队列实现的原理如下图:

延迟队列原理图

原理解析: 1、生产者发送消息的队列中,且针对该队列没有消费者 2、由于队列没有消费者,消息在过期之后会进入到死信队列中 3、监听死信队列,并对死信队列中的消息进行消费

通过队列中的消息延迟转发实现延迟队列。

RabbitMq 延迟队列本身的特性,导致的问题。

通过查看相关RabbitMq 介绍内容,进行相关测试。

测试代码如下

// 发送消息
@RequestMapping("/send-msg")
public String placeOrder(@RequestParam(value = "expiration",defaultValue = "60000")String expiration){
	// msg 属性,如 TTL
	MessageProperties msgProperties = new MessageProperties();
    msgProperties.setExpiration(expiration);
	// msg 内容
    Message msg = new Message("send-msg".getBytes(),msgProperties);
    CorrelationData correlationData = new CorrelationData(orderNo);
	// 发送消息
	rabbitTemplate.send(RabbitMqConfigEnum.ORDER_DELAY.Exchange(),
                    RabbitMqConfigEnum.ORDER_DELAY.RoutingKey(),msg,correlationData);
        return "success";
}
//消费死信队列
@RabbitListener(queues = "ORDER_DELAY_DEAD_LETTER_QUEUE")
public void receiveMessage(Message message){
	log.info("【消费:{}】 ",new String(message.getBody()));
}

测试步骤

1、先发送一条 TTL = 60000 ms(1分钟)的消息 msg-1 到队列中。 2、在发送一条 TTL = 1ms 的消息 msg-2 到队列中

测试结果 msg-1 消费完之后,消费 msg-2

测试结论

测试结论图

RabbitMq 队列是有顺序的,按照先进先出的原则。消息是否从 Queue 进入 Dead Letter Queue 需要从头部第一条信息开始判断,当第一条消息进入 Dead Letter Queue 中后,第二条消息变成第一条,然后依次循环操作。 也就是说,即使 第二条消息 msg-2 比 第一条 msg-1 先过期,也需要等到 msg-1 进入 Dead Letter Queue 中时 msg-2 才会进入到 Dead Letter Queue 中。

从以上结论得出,使用 RabbitMq 实现的延迟队列,无法按照随机过期时间,精准消费延时的消息。针对随机分布式的过期时间,RabbitMq 延迟队列无能为力。如果是定制的多个过期时间,可以针对不同的时间分别定制不同延时队列组合。

延时队列组合

延迟队列---实现未支付订单状态更改

背景

在系统中,存在下单操作。而下单的支付操作对接的一般也是第三方平台的支付系统。 用户下单生成订单,订单状态为待支付,等待第三方支付回调更新状态。 在规定时间内:如 15 分钟内,如果订单仍然为 待支付状态,修改订单状态为 取消。

常规做法

通过 定时任务 进行处理。

定时任务 处理存在的问题: 1、订单状态的时效性无法得到保障 2、集中处理订单数据,数据量大时,可能导致瞬时的mysql 写操作增加。

使用 RabbitMq 进行状态延迟变更可行性分析

  • 1、如何保证消息的可靠发送?

    通过 confirm 确认机制,保证消息至少发送一次

  • 2、如何保证消息一定会被消费,且只消费一次?

    通过持久化队列,持久化消息的方式,只要 消息发送到 RabbitMq 中,只要未被确认消费,消息就会一直存在。 由于消息的可靠发送,导致的消息可能重复发送的问题,通过消费接口的幂等操作。保证消息不会重复消费。 如:UPDATE 订单表 SET 订单状态 = 订单取消 where 订单状态 = 待支付 AND 订单号 = orderNo

  • 3、使用 RabbitMq 为什么优于定时任务?

    a、RabbitMq 能够实现 订单状态近实时的状态的变更。

    b、根据用户下单的时间不同,分散操作订单状态的时间点,防止非用户行为导致的瞬时数据库操作压力

  • 4、队列长度达到阈值,是否导致未过期消息提前进入死信队列?

    首先,RabbitMq 队列在未指定队列长度时,默认是没有上限的。其上限与机器内存,磁盘空间等有关。

由于代码简单这里不进行代码黏贴。 RabbitMq_延迟队列_Demo结构

关注公众号,回复【RabbitMQ 延迟队列 Demo】获取测试代码

精彩内容推送,请关注公众号:【WTF名字好难取】!

转载于:https://my.oschina.net/u/3787570/blog/3047700

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值