【问题标题】:Consuming from multiple queues at once with aioamqp使用 aioamqp 一次从多个队列中消费
【发布时间】:2016-08-10 09:53:34
【问题描述】:

是否可以通过 aioamqp 使用一个通道一次消耗多个队列?

免责声明:我在项目问题跟踪器中创建了一个issue,但我真的想知道我所做的是否有意义。

【问题讨论】:

    标签: python rabbitmq python-asyncio


    【解决方案1】:

    我认为AMQP协议中没有这个功能(假设我对协议的理解是正确的)。

    如果您希望从队列中消费,您必须在通道上发出 basic.consume 调用。此调用所需的参数是queue_name,它是一个“阻塞”(不是阻塞连接而是阻塞通道)调用,其中响应是队列中的一个对象。

    长话短说:每个消费者在等待队列对象时都必须拥有对通道的独占访问权。

    好的,所以我最初的想法是错误的。在深入了解AMQP 之后,我发现它实际上确实支持一个渠道上的多个消费者。但是,它确实允许服务器在需要时设置它们的限制。不幸的是,我找不到有关 RabbitMQ 特定案例的任何信息。所以我假设没有这样的限制。总而言之:这是图书馆的问题。

    但是解决方法仍然有效:只需为每个消费者创建一个频道。它应该可以正常工作。

    【讨论】:

    • 你说得对,我只会并行打开多个通道,因为这是一个便宜的操作。谢谢!!
    • 相当肯定 RabbitMQ 支持从同一通道消费多个队列。不过,它们都会被传递到同一个回调。
    • @eandersson 是的,我已经深入研究了 AMQP 规范,看来您是正确的。更新了答案。
    • 我已经创建了一个相关问题here,以防万一有人想介入。我决定放弃aioamqp,因为从错误跟踪器中的cmets来看,作者并不高兴就目前的 API 设计而言,有些事情很难做到。
    【解决方案2】:

    ammoo 有效:

    import asyncio
    
    from ammoo import connect
    
    
    async def consume(channel, queue_name):
        async with channel.consume(queue_name, no_ack=True) as consumer:
            async for message in consumer:
                print('Message from {}: {}'.format(queue_name, message.body))
                if message.body == b'quit':
                    print('Consumer for queue {} quitting'.format(queue_name))
                    break
    
    
    async def main():
        async with await connect('amqp://localhost/') as connection:
            async with connection.channel() as channel:
                await channel.declare_queue('queue_a')
                await channel.declare_queue('queue_b')
    
                await asyncio.gather(
                    consume(channel, 'queue_a'),
                    consume(channel, 'queue_b')
                )
                print('Both consumers are done')
    
    
    
    if __name__ == '__main__':
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
    

    输出:

    # python3 test.py 
    Message from queue_a: b'hello queue a'
    Message from queue_b: b'hello queue b'
    Message from queue_a: b'quit'
    Consumer for queue queue_a quitting
    Message from queue_b: b'another message for queue b'
    Message from queue_b: b'quit'
    Consumer for queue queue_b quitting
    Both consumers are done
    

    免责声明:我是图书馆的作者

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      • 1970-01-01
      • 2016-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多