如何使用py-amqplib等待多个队列上的消息

时间:2009-11-27 06:34:39

标签: python message-queue rabbitmq amqp py-amqplib

我正在使用 py-amqplib 来访问Python中的RabbitMQ。应用程序不时收到侦听某些MQ主题的请求。

第一次收到此请求时,它会创建一个AMQP连接和一个频道,并启动一个新线程来侦听消息:

    connection = amqp.Connection(host = host, userid = "guest", password = "guest", virtual_host = "/", insist = False)
    channel = connection.channel()

    listener = AMQPListener(channel)
    listener.start()

AMQPListener 非常简单:

class AMQPListener(threading.Thread):
    def __init__(self, channel):
        threading.Thread.__init__(self)
        self.__channel = channel

    def run(self):
        while True:
            self.__channel.wait()

创建连接后,它会订阅感兴趣的主题,如下所示:

channel.queue_declare(queue = queueName, exclusive = False)
channel.exchange_declare(exchange = MQ_EXCHANGE_NAME, type = "direct", durable = False, auto_delete = True)
channel.queue_bind(queue = queueName, exchange = MQ_EXCHANGE_NAME, routing_key = destination)

def receive_callback(msg):
    self.queue.put(msg.body)

channel.basic_consume(queue = queueName, no_ack = True, callback = receive_callback)

这一切都很好。但是,它在后续请求订阅另一个主题时失败。在后续请求中,我重新使用AMQP连接和AMQPListener线程(因为我不想为每个主题启动新线程),当我在 channel.queue_declare()上面调用代码块时方法调用永远不会返回我还尝试在此时创建一​​个新频道, connection.channel()调用永远不会返回。

我能够让它工作的唯一方法是为每个主题创建一个新的连接,通道和监听器线程(即.route_key),但这实际上并不理想。我怀疑是wait()方法以某种方式阻止整个连接,但我不知道该怎么做。当然,我应该能够使用单个侦听器线程接收带有多个路由键(甚至是几个通道)的消息?

一个相关的问题是:当该主题不再受关注时,我如何停止监听线程?如果没有消息, channel.wait()调用似乎会永久阻止。我能想到的唯一方法是向队列发送一个虚拟消息,这会“毒害”它,即。被听众解释为停止的信号。

1 个答案:

答案 0 :(得分:1)

如果您希望每个频道有多个comsumer,请使用 basic_consume()附加另一个,然后使用 channel.wait()。它将通过 basic_consume()收听所有队列。确保为每个 basic_consume()定义不同的消费者代码。

如果要取消队列中的特定消费者(取消收听特定主题),请使用 channel.basic_cancel(consumer_tag)