工作中有些场景需要用到延迟队列,大概对RabbitMQ延迟队列场景有一些了解,网上大部分的场景应用于:订单超时、定时执行等。
而我需要延迟队列的场景是:有一批机器需要监控这个延迟队列长度,一旦满足就提前预备机器,准备执行任务。通过监控延迟队列,我可以准确、可靠的清楚,接下来的某个时间我一定会执行哪些任务。相较于传统通过API来唤醒设备,提升了稳定性。我只需要关注一点:发布消息。
同时也了解到,大部分使用RabbitMQ实现延迟队列从两个方向入手:
接下来,我将会从这两个方向逐一进行,分析利弊。
阅读本文,你将获得:
通过死信队列来解决延迟队列给人的感觉是「曲线救国」的方案,因为在原生RabbitMQ中并不直接支持延迟队列。其原理就是把消息发给一个中间队列,这个中间队列预设了TTL过期时间,并绑定了死信队列和死信交换机,当中间队列的消息过期时,就会发送到死信队列中。届时,死信队列就充当了延迟队列。
Python代码如下:
- # -*- coding: utf-8 -*-
- from mq import channel
-
- DEAD_EXCHANGE_NAME = 'dead.exchange'
- DEAD_QUEUE_NAME = 'dead.queue'
- DEAD_ROUTING_KEY = 'dead.routing.key'
-
- QUEUE_NAME = 'normal.queue'
-
- # 声明死信交换机
- channel.exchange.declare(DEAD_EXCHANGE_NAME, exchange_type="direct")
- # 声明死信队列
- channel.queue.declare(DEAD_QUEUE_NAME, durable=True)
- # 死信队列绑定死信交换机和死信路由
- channel.queue.bind(
- queue=DEAD_QUEUE_NAME,
- exchange=DEAD_EXCHANGE_NAME,
- routing_key=DEAD_ROUTING_KEY,
- )
-
- # 声明正常队列,并绑定死信交换机和死信路由,约束队列TTL为10秒
- arguments = {
- "x-dead-letter-exchange": DEAD_EXCHANGE_NAME,
- "x-dead-letter-routing-key": DEAD_ROUTING_KEY,
- "x-message-ttl