[英]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.