使用RabbitMQ实现TTL机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用RabbitMQ实现TTL机制相关的知识,希望对你有一定的参考价值。
参考技术A我们想象这样一个场景,在京东下单,订单创建成功,等待支付,一般会给30分钟的时间,开始倒计时。如果在这段时间内用户没有支付,则默认订单取消。这个怎么实现?
TTL,Time to Live 的简称,即过期时间。RabbitMQ 可以对消息和队列两个维度来设置TTL。
任何消息中间件的容量和堆积能力都是有限的,如果有一些消息总是不被消费掉,那么需要有一种过期的机制来做兜底。目前有两种方法可以设置消息的TTL。
1)通过Queue属性设置,队列中所有消息都有相同的过期时间。
2)对消息自身进行单独设置,每条消息的TTL 可以不同。
如果两种方法一起使用,则消息的TTL 以两者之间较小数值为准。通常来讲,消息在队列中的生存时间一旦超过设置的TTL 值时,就会变成“死信”(Dead Message),消费者默认就无法再收到该消息。“死信”要被取出来消费,需要特殊的手段,我们以后再做介绍。
1)如果不设置TTL,则表示此消息不会过期;
2)如果TTL设置为0,则表示除非此时可以直接将消息投递到消费者,否则该消息会被立即丢弃;
注意理解message-ttl 、x-expires 这两个参数的区别,有不同的含义。但是这遵循上面的默认规则。一般TTL相关的参数单位都是毫秒(ms)
添加pom.xml文件依赖
application.properties添加rabbitmq连接信息
启动入口类
RabbitConfig类
PayController类实现
rabbitmq延迟消息
一、RabbitMQ的两个概念
使用RabbitMQ来实现延迟消息必须先了解RabbitMQ的两个概念:消息的TTL和死信Exchange,通过这两者的组合来实现上述需求。
1、消息的TTL(Time To Live)
消息的TTL就是消息的存活时间。RabbitMQ可以对队列和消息分别设置TTL。对队列设置就是队列没有消费者连着的保留时间,也可以对每一个单独的消息做单独的设置。超过了这个时间,我们认为这个消息就死了,称之为死信。
我们创建一个队列queue.temp,在Arguments 中添加x-message-ttl 为5000 (单位是毫秒),那每一个进入这个队列的消息在5秒后会消失。
2.死信交换器 Dead Letter Exchanges
一个消息在满足如下条件下,会进死信交换机,记住这里是交换机而不是队列,一个交换机可以对应很多队列。
(1) 一个消息被Consumer拒收了,并且reject方法的参数里requeue是false。也就是说不会被再次放在队列里,被其他消费者使用。
(2)上面的消息的TTL到了,消息过期了。
(3)队列的长度限制满了。排在前面的消息会被丢弃或者扔到死信交换机上。
Dead Letter Exchange其实就是一种普通的exchange,和创建其他exchange没有两样。只是在某一个设置Dead Letter Exchange的队列中有消息过期了,会自动触发消息的转发,发送到Dead LetterExchange中去。
二、示例
我们现在可以测试一下延迟队列。
(1)创建死信交换器 exchange.ordertimeout (fanout)
(2)创建队列queue.ordertimeout
(3)建立死信交换器 exchange.ordertimeout 与队列queue.ordertimeout 之间的绑定
(4)创建队列queue.ordercreate,Arguments添加
x-message-ttl=10000 x-dead-letter-exchange: exchange.ordertimeout
(5)测试:向queue.ordercreate队列添加消息,等待10秒后消息从queue.ordercreate队列消失,
步骤:
(1)创建死信交换器 exchange.ordertimeout (fanout)
(2)创建队列queue.ordertimeout
(3)建立死信交换器 exchange.ordertimeout 与队列queue.ordertimeout 之间的绑定
(4)创建队列queue.ordercreate,Arguments添加
x-message-ttl=10000 x-dead-letter-exchange: exchange.ordertimeout
(5)测试:向queue.ordercreate队列添加消息,等待10秒后消息从queue.ordercreate队列消失,
以上是关于使用RabbitMQ实现TTL机制的主要内容,如果未能解决你的问题,请参考以下文章