簡體   English   中英

在 python / pika 中消費多個隊列

[英]Consume multiple queues in python / pika

我正在嘗試創建一個訂閱多個隊列的消費者,然后在消息到達時對其進行處理。

問題是,當第一個隊列中已經存在一些數據時,它會消耗第一個隊列,而永遠不會去消耗第二個隊列。 但是,當第一個隊列為空時,它會執行 go 到下一個隊列,然后同時消耗兩個隊列。

我首先實現了線程,但想避開它,當 pika 庫為我完成它時沒有太多復雜性。 下面是我的代碼:

import pika

mq_connection = pika.BlockingConnection(pika.ConnectionParameters('x.x.x.x'))
mq_channel = mq_connection.channel()
mq_channel.basic_qos(prefetch_count=1)


def callback(ch, method, properties, body):
    print body
    mq_channel.basic_ack(delivery_tag=method.delivery_tag)

mq_channel.basic_consume(callback, queue='queue1', consumer_tag="ctag1.0")
mq_channel.basic_consume(callback, queue='queue2', consumer_tag="ctag2.0")
mq_channel.start_consuming()

一種可能的解決方案是使用非阻塞連接並使用消息。

import pika


def callback(channel, method, properties, body):
    print(body)
    channel.basic_ack(delivery_tag=method.delivery_tag)


def on_open(connection):
    connection.channel(on_channel_open)


def on_channel_open(channel):
    channel.basic_consume(callback, queue='queue1')
    channel.basic_consume(callback, queue='queue2')


parameters = pika.URLParameters('amqp://guest:guest@localhost:5672/%2F')
connection = pika.SelectConnection(parameters=parameters,
                                   on_open_callback=on_open)

try:
    connection.ioloop.start()
except KeyboardInterrupt:
    connection.close()

這將連接到多個隊列並相應地使用消息。

問題很可能是第一個調用發出了 Basic.Consume 並且在發出第二個調用之前已經從預先填充的隊列中接收到消息。 您可能想嘗試將 QoS 預取計數設置為 1,這將限制 RabbitMQ 一次向您發送多條消息。

與上面第一個答案中的評論類似,我能夠使用 pika 1.1.0 和以下內容獲得類似的結果:

 import pika def queue1_callback(ch, method, properties, body): print(" [x] Received queue 1: %r" % body) def queue2_callback(ch, method, properties, body): print(" [x] Received queue 2: %r" % body) def on_open(connection): connection.channel(on_open_callback = on_channel_open) def on_channel_open(channel): channel.basic_consume('queue1', queue1_callback, auto_ack = True) channel.basic_consume('queue2', queue2_callback, auto_ack = True) credentials = pika.PlainCredentials('u', 'p') parameters = pika.ConnectionParameters('localhost', 5672, '/', credentials) connection = pika.SelectConnection(parameters = parameters, on_open_callback = on_open) Try: connection.ioloop.start() except KeyboardInterrupt: connection.close() connection.ioloop.start()

值得注意的是,上述解決方案僅在 auto_ack 設置為 True 時才有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM