MQ本身并不支持直接的延时队列实现,但是我们可以通过RabbitMQ的消息TTL和Dead Letter规则来实现
Time TO Live (TTL): RabbitMQ可以针对Queue设置x-expires 或者 针对Message设置 x-message-ttl,来控制消息的生存时间
Dead Letter 死信 RabbitMQ官网这样定义死信消息:
. 消息被拒绝(basic.reject或basic.nack)并且requeue=false.
. 消息TTL过期
队列达到最大长度(队列满了,无法再添加数据到mq中)
Dead Letter Exchanges(DLX)死信交换机 MQ默认的死信消息是丢弃的,但是我们可以通过设置以下两个属性让死信消息转发到我们指定的队列。
x-dead-letter-exchange:出现dead letter之后将dead letter重新发送到指定exchange
x-dead-letter-routing-key:出现dead letter之后将dead letter重新按照指定的routing-key发送
延时队列实现: 了解了MQ队列的TTL和Dead Letter之后,我们就可以通过这两个特性来实现,首先我们通过设置消息或者队列的TTL来设置消息在指定时间后成为死信,再设置死信消息的路由转发规则到特定队列,消费者通过监听这个特定队列就能实现延时队列的效果。
代码实现
生产者发送消息:ttlQueue存放过期时间的队列,deadLetterQueue死信转发队列,seconds是过期时间
Only when expired messages reach the head of a queue will they actually be discarded (or dead-lettered)
所以我才称之为MQ的伪延时队列,这种延时队列在消息TTL不同的情况下并不能实现真正的延时消费。