如何使用rabbitmq-delayed-message-exchange插件在rabbitmq中发送延迟消息?

时间:2016-02-17 06:16:16

标签: python rabbitmq

我已经安装了插件,可以从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函数

感谢任何帮助

2 个答案:

答案 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()