RabbitMQ延时队列(实现定时任务)

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

RabbitMQ延时队列(实现定时任务) 

 常用解决方案: spring的 schedule 定时任务轮询数据库

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

解决:rabbitmq的消息TTL和死信Exchange结合

RabbitMQ延时队列(实现定时任务)

 

二、

1、消息的TTL(Time To Live)

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

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

        队列设置就是队列没有消费者连着的保留时间,也可以对没一个单独的消息做单独的设置。超过这个时间,我们认为这个消息死了,称之为死信

        如果队列设置了,消息也设置了,那么会取小的。所以一个消息如果被路由到不同的队列中,这个消息的死亡时间又可能不一样(不同的队列设置)。这里单讲单个消息的TTL,因为它才是实现延迟任务的关键。可以通过设置消息的expiration字段或者x-message-ttl属性来设置时间,两种是一样的效果

3、Dead Letter Exchanges(DLX)

        一个消息在满足如下条件,会进死信路由,这里是指路由,而不是队列,一个路由可以对应很多队列

       1)、一个消息被Consumer拒收了,并且reject方法的参数里request是false.也就是说不会被再次放在队列里。被其他消费者使用。

        2)、上面的消息TTL到了。消息过期了

        3)、队列的长度限制满了。排在前面的消息会被丢弃或者扔到死信路由上

4、Dea Letter Exchange 其实就是一种普通的exchange,和创建其他exchange没有两样,只是在某一个设置Dead Letter Exchange 的队列中有消息过期了,会自动触发消息的转发,发送到Dead Letter Exchange中区。

我们既可以控制消息在一段时间后变成死信,又可以耦控制变成死信的消息被路由到某一个指定的交换机,结合二者。其实就可以实现一个延时队列

总结;给消息设置过期------(过期 通过死信路由)---->指定的交换机(exchange)--------->再到一个队列--(过期时间后)--------->特点交换器(exchange)------->指定队列---->consumer消费

RabbitMQ延时队列(实现定时任务) 

 RabbitMQ延时队列(实现定时任务)

 

 附:消息的整个流转过程

RabbitMQ延时队列(实现定时任务)

 

上一篇:springboot集成rabbitMq时踩的坑


下一篇:EasyCVR后台添加操作记录功能开发分享(附代码)