我已经安装了插件,可以从rabbitmq-delayed-message-exchange发送延迟消息。
我无法在python中找到任何帮助。我刚刚开始使用rabbitmq。
以下是我一直在尝试的内容:
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare("test-x", type="x-delayed-message", arguments={"x-delayed-type":"direct"})
channel.queue_declare(queue='task_queue',durable=True)
channel.queue_bind(queue="task_queue", exchange="test-x", routing_key="task_queue")
channel.basic_publish(exchange='test-x',routing_key='task_queue',body='Hello World! Delayed',arguments={"x-delay":100})
print(" [x] Sent 'Hello World! Delayed'")
connection.close()
以下是列出的交易所:
sudo rabbitmqctl list_exchanges
Listing exchanges ...
amq.direct direct
test-x x-delayed-message
amq.fanout fanout
amq.match headers
amq.headers headers
direct
amq.rabbitmq.trace topic
amq.topic topic
amq.rabbitmq.log topic
我不知道如何将延迟参数传递给basic_publish函数
感谢任何帮助
答案 0 :(得分:4)
您需要将x-delay
标头添加到邮件属性中,并以毫秒为单位指定延迟值。试试这个:
channel.basic_publish(
exchange='test-x',
routing_key='task_queue',
body='Hello World! Delayed',
properties=pika.BasicProperties(headers={"x-delay": 1000})
)
答案 1 :(得分:2)
你实际上可以在不使用插件的情况下延迟消息。 Rabbit队列中的消息可以以两种方式延迟 - 使用QUEUE TTL - 使用Message TTL 如果队列中的所有消息都要延迟一段时间,请使用队列TTL。 如果每条消息都必须按不同的时间延迟,请使用Message TTL。 我用python3和pika模块解释了它。 pika BasicProperties参数'expiration'(以毫秒为单位)必须设置为延迟队列中的延迟消息。 设置到期时间后,将消息发布到delayed_queue(“非消费者等待消费的实际队列”),一旦delayed_queue中的消息到期,消息将使用exchange'amq.direct'路由到实际队列
def delay_publish(self, messages, queue, headers=None, expiration=0):
"""
Connect to RabbitMQ and publish messages to the queue
Args:
queue (string): queue name
messages (list or single item): messages to publish to rabbit queue
expiration(int): TTL in milliseconds for message
"""
delay_queue = "".join([queue, "_delay"])
logging.info('Publishing To Queue: {queue}'.format(queue=delay_queue))
logging.info('Connecting to RabbitMQ: {host}'.format(
host=self.rabbit_host))
credentials = pika.PlainCredentials(
RABBIT_MQ_USER, RABBIT_MQ_PASS)
parameters = pika.ConnectionParameters(
rabbit_host, RABBIT_MQ_PORT,
RABBIT_MQ_VHOST, credentials, heartbeat_interval=0)
connection = pika.BlockingConnection(parameters)
channel = connection.channel()
channel.queue_declare(queue=queue, durable=True)
channel.queue_bind(exchange='amq.direct',
queue=queue)
delay_channel = connection.channel()
delay_channel.queue_declare(queue=delay_queue, durable=True,
arguments={
'x-dead-letter-exchange': 'amq.direct',
'x-dead-letter-routing-key': queue
})
properties = pika.BasicProperties(
delivery_mode=2, headers=headers, expiration=str(expiration))
if type(messages) not in (list, tuple):
messages = [messages]
try:
for message in messages:
try:
json_data = json.dumps(message)
except Exception as err:
logging.error(
'Error Jsonify Payload: {err}, {payload}'.format(
err=err, payload=repr(message)), exc_info=True
)
if (type(message) is dict) and ('data' in message):
message['data'] = {}
message['error'] = 'Payload Invalid For JSON'
json_data = json.dumps(message)
else:
raise
try:
delay_channel.basic_publish(
exchange='', routing_key=delay_queue,
body=json_data, properties=properties)
except Exception as err:
logging.error(
'Error Publishing Data: {err}, {payload}'.format(
err=err, payload=json_data), exc_info=True
)
raise
except Exception:
raise
finally:
logging.info(
'Done Publishing. Closing Connection to {queue}'.format(
queue=delay_queue
)
)
connection.close()