RabbitMQ延迟队列实现(Python)
基础原理
- Time To Live:RabbitMQ可设置队列过期时间(x-message-ttl),或设置消息过期时间(expiration)。
- Dead Letter Exchange:当消息成为死信后,会被重新发送到另⼀个exchange,这个exchange就是DLX。
- Dead Letter条件:消息被拒绝、过期、队列已满。
Python实现
Consumer:
#!/usr/bin/env python
# coding=utf-8
import pika
import datetime
DEAD_EXCHANGE_NAME = "dead_exchange"
DEAD_QUEUE_NAME = "dead_queue"
DEAD_ROUTING_KEY = "dead_test"
def Callback(channel, method, properties, body):
print "time: ", datetime.datetime.now()
print "Receive msg: ", body
if __name__ == '__main__':
credentials = pika.PlainCredentials("test", "test")
connection = pika.BlockingConnection(pika.ConnectionParameters(host = '127.0.0.1',port = 5672,virtual_host = '/',credentials = credentials))
# 创建信道
channel = connection.channel()
# exchange声明
channel.exchange_declare(exchange = DEAD_EXCHANGE_NAME, exchange_type = "topic")
# queue声明
channel.queue_declare(queue = DEAD_QUEUE_NAME)
channel.queue_bind(queue = DEAD_QUEUE_NAME , exchange = DEAD_EXCHANGE_NAME, routing_key = DEAD_ROUTING_KEY)
channel.basic_consume(on_message_callback = Callback, queue = DEAD_QUEUE_NAME, auto_ack=True)
channel.start_consuming()
Producer:
#!/usr/bin/env python
# coding=utf-8
import pika
import datetime
DEAD_EXCHANGE_NAME = "dead_exchange"
DEAD_QUEUE_NAME = "dead_queue"
DEAD_ROUTING_KEY = "dead_test"
TTL_EXCHANGE_NAME = "ttl_exchange"
TTL_QUEUE_NAME = "ttl_queue"
if __name__ == '__main__':
credentials = pika.PlainCredentials("test", "test")
connection = pika.BlockingConnection(pika.ConnectionParameters(host = '127.0.0.1',port = 5672,virtual_host = '/',credentials = credentials))
# 创建信道
channel = connection.channel()
# 死信exchange、queue声明
channel.exchange_declare(exchange = DEAD_EXCHANGE_NAME, exchange_type = "topic")
channel.queue_declare(queue = DEAD_QUEUE_NAME)
channel.queue_bind(queue = DEAD_QUEUE_NAME , exchange = DEAD_EXCHANGE_NAME, routing_key = DEAD_ROUTING_KEY)
# dead letter转发参数
arguments = {}
arguments['x-dead-letter-exchange'] = DEAD_EXCHANGE_NAME
arguments['x-dead-letter-routing-key'] = DEAD_ROUTING_KEY
arguments['x-message-ttl'] = 10000 # 单位:ms
# 辅助ttl exchange、queue声明
channel.exchange_declare(exchange = TTL_EXCHANGE_NAME, exchange_type="topic")
channel.queue_declare(queue = TTL_QUEUE_NAME, arguments=arguments)
channel.queue_bind(queue = TTL_QUEUE_NAME , exchange = TTL_EXCHANGE_NAME, routing_key = "ttl_test")
print datetime.datetime.now()
channel.basic_publish(exchange=TTL_EXCHANGE_NAME, routing_key = "ttl_test", body = "Hello world.")
测试结果
producer:
2021-09-02 01:57:46.633364
consumer:
time: 2021-09-02 01:57:56.637281
Receive msg: Hello world.