Pika:如何同步使用消息

时间:2014-09-14 15:49:20

标签: python rabbitmq amqp pika

我想定期运行一个进程(比如每10分钟一次,或每小时一次),从队列中获取所有消息,处理它们然后退出。有没有办法用pika或者我应该使用不同的python库?

3 个答案:

答案 0 :(得分:6)

我认为这里的理想解决方案是使用basic_get方法。它将获取单个消息,但如果队列已经为空,则将返回None。这样做的好处是你可以用一个简单的循环清除队列,然后在返回None后简单地断开循环,另外可以安全地运行带有多个消费者的basic_get。

此示例基于我自己的库; amqpstorm,但您也可以使用pika轻松实现相同的功能。

from amqpstorm import Connection

connection = Connection('127.0.0.1', 'guest', 'guest')
channel = connection.channel()
channel.queue.declare('simple_queue')
while True:
    result = channel.basic.get(queue='simple_queue', no_ack=False)
    if not result:
        print("Channel Empty.")
        # We are done, lets break the loop and stop the application.
        break
    print("Message:", result['body'])
    channel.basic.ack(result['method']['delivery_tag'])
channel.close()
connection.close()

答案 1 :(得分:3)

这对你有用吗?

  1. 将当前队列长度测量为N = queue.method.message_count
  2. 使回调计入已处理的邮件,并在处理N后立即致电channel.stop_consuming
  3. 因此,客户端代码将是这样的:

    class CountCallback(object):
        def __init__(self, count):
            self.count = count
    
        def __call__(self, ch, method, properties, body):
            # process the message here
            self.count -= 1
            if not self.count:
                ch.stop_consuming()
    
    channel = conn.channel()
    queue = channel.queue_declare('tasks')
    callback = CountCallback(queue.method.message_count)
    channel.basic_consume(callback, queue='tasks')
    channel.start_consuming()
    

答案 2 :(得分:0)

@eandersson

  

此示例基于我自己的库; amqpstorm,但您也可以使用pika轻松实现相同的功能。

已针对amqpstorm 2.6.1更新:

from amqpstorm import Connection

connection = Connection('127.0.0.1', 'guest', 'guest')
channel = connection.channel()
channel.queue.declare('simple_queue')
while True:
    result = channel.basic.get(queue='simple_queue', no_ack=False)
    if not result:
        print("Channel Empty.")
        # We are done, lets break the loop and stop the application.
        break
    print("Message:", result.body)
    channel.basic.ack(result.method['delivery_tag'])
channel.close()
connection.close()