• RabbitMQ延时队列


    1、场景:

    比如未付款订单,超过一定时间后,系统自动取消订单,并释放占用物品


    2、上述场景的解决方案:

    1)spring schedule的定时任务轮询数据库

    缺点:消耗系统内存,增加数据库压力,存在较大的时间误差

    (例如如果订单30分钟未支付时取消订单,且定时任务30分钟执行一次,那么一个订单最晚会59分钟才会被定时任务扫描到已取消,例如定时任务在0分钟时执行,恰巧订单在一分钟时来了,定时任务在30分钟时扫描订单,发现订单还没过期,但是31分钟订单恰好过期,于是等到60分钟,定时任务再次扫描时,才能扫描到这个过期订单,所以订单在一分钟被创建,60分钟才被发现过期)

    image-20220227152229409


    2)RabbitMQ延时队列

    rabbitmq延时队列 (消息ttl和死信Exchange结合)

    image-20220227152716727


    3、消息的TTL(time to live)

    消息的ttl就是消息的存活时间

    RabbitMQ可以对队列和消息分别设置TTL

    • 对队列设置ttl就是,消息在队列的逗留时间;也可以对每一个单独的消息做单独的设置。超过了这个时间,我们就认为这个消息死了,称之为死信

    • 如果队列设置了ttl,消息也设置了,会取两者之间较小的。可以通过设置消息的expiration字段或者x-message-ttl属性来设置时间,两者是一样的效果


    4、Dead Letter Exchange (DLX)

    image-20220227160755346


    5、延时队列的实现

    设置队列过期时间实现延时队列 (推荐)

    image-20220227161640741


    设置消息过期时间来实现延时队列

    image-20220227163336965


    6、延时队列定时关闭订单模拟

    交换机,队列以及路由键的相关情况如下:

    image-20220227165605031

    p消息,经过交换机order-event-exchange路由到延时队列order.delay.queue,延时队列设置了如上三个属性,当延时队列中的消息过期后,会转到指定的Dead Letter Exchage(order-event-exchange),Dead Letter Exchage在将消息路由到指定的队列进行处理



    7、消息丢失、积压、重复的解决方案

    如何保证消息的可靠性

    1、消息丢失

    消息发送出去,由于网络原因没有到达服务器(producer到broker)

    • 做好容错方法(try catch),发送消息可能会网络失败,失败后要有重试机制,科技路到数据库,采用定期扫描重发的方式

    • 做好日志记录,每个消息是否被服务器收到,应该记录

    • 做好定期重发,定期去数据库扫描未成功发送的消息进行重发

    消息抵达Broker,Broker要将消息写入磁盘(持久化)才算成功。此时Broker尚 未持久化完成,宕机

    • publisher也必须加入确认回调机制,确认成功的消息,修改数据库消息状态

    自动ACK的状态下。消费者收到消息,但没来得及消息然后宕机

    • 一定开启手动ACK,消费成功才移除,失败或者没来得及处理就noAck并重新入队


    2、消息重复

    消息消费成功,事务已经提交,ack时,机器宕机。导致没有ack成功,Broker的消息 重新由unack变为ready,并发送给其他消费者(当消息正在被消费者消费时,消息是unack状态,当消息被reject时,由unack变为ready;当消息被正常消费时,从队列移除)

    • 消费者的业务消费接口应该设计为幂等性的。比如扣库存有 工作单的状态标志

    • 使用防重表(redis/mysql),发送消息每一个都有业务的唯 一标识,处理过就不用处理

    • rabbitMQ的每一个消息都有redelivered字段,可以获取是否 是被重新投递过来的,而不是第一次投递过来的


    3、消息积压

    消费者宕机积压

    消费者消费能力不足积压

    发送者发送流量太大

    • 上线更多的消费者,进行正常消费

    • 上线专门的队列消费服务,将消息先批量取出来,记录数据库,离线慢慢处理

  • 相关阅读:
    【内核】linux内核启动流程详细分析【转】
    【Linux】Linux基本命令扫盲【转】
    【Linux高级驱动】linux设备驱动模型之平台设备驱动机制【转】
    【Git】Git与GitHub 入门【转】
    usbnet驱动深入分析-usb虚拟网卡host端【转】
    USB设备被识别流程【转】
    LinuxUSB驱动程序调试--009:编写应用程序---验证协议【转】
    公积金条例久拖不改是谁在博弈?
    Android事件机制全然解析
    《Java并发编程实战》第二章 线程安全性 读书笔记
  • 原文地址:https://www.cnblogs.com/houchen/p/16002672.html
Copyright © 2020-2023  润新知