在处理来自主队列的消息时如何处理来自临时队列的消息?

时间:2019-07-14 21:35:19

标签: python rabbitmq pika

我正在一个项目中,我们使用微服务架构来处理文档。假设在下图中,微服务A 是API,然后微服务B 对上载的文档进行一些处理,然后微服务C 完成处理(稍后将它们称为 A,B,C B1 )。 该体系结构的链接:Architecture(对不起,我想直接发布该图像,但是我的信誉不高。)

棘手的部分现在到了,假设 B 分离页面并将消息发送到 B1 ,该消息在页面级别处理文档(即计算字),然后将结果返回到 B 。因此,存在“正常”流程,其中 A B 发送消息, B 开始处理此消息,然后将消息发送至 B1 B1 有效,完成并回复。此时, B 应该可以得到答复,同时仍在处理原始消息,但这不会发生。

我的感觉是prefetch_count阻止 B 处理更多邮件。我正在使用prefetch_count = 1来尽可能地快速便捷地进行缩放,但是也许我对这个参数的理解是错误的,我们稍后再看代码。

我试图在 B 上创建一个新频道,以处理 B x B1 互动,但没有成功。我唯一能使它工作的方法是创建一个新连接,因此基本上 B 会有两个RabbitMq连接。

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.basic_qos(prefetch_count=1)
channel.exchange_declare(exchange='test', exchange_type='direct')
channel.queue_declare(queue='receiver1', durable=True, exclusive=True)
channel.queue_bind(exchange='test', queue='receiver1', routing_key='a.done')

def inner_callback(ch, method, props, body):
    print(" [x] %r:%r" % (method.routing_key, body))
    ch.basic_ack(delivery_tag=method.delivery_tag)

def callback(ch, method, props, body):
    print(" [x] %r:%r" % (method.routing_key, body))
    channel2 = connection.channel()
    channel2.basic_qos(prefetch_count=1)

    result = channel2.queue_declare(queue='', exclusive=True)
    callback_queue = result.method.queue
    channel2.queue_bind(exchange='test', queue=callback_queue, routing_key=callback_queue)
    consumer_tag = channel2.basic_consume(queue=callback_queue, on_message_callback=inner_callback)

    channel.basic_publish(exchange='test',
                          routing_key='b1.run',
                          body="page",
                          properties=pika.BasicProperties(
                              reply_to=callback_queue,
                              correlation_id=props.correlation_id))
    response = False
    while not response:
        connection.process_data_events()
    channel.basic_cancel(consumer_tag)
    ch.basic_ack(delivery_tag=method.delivery_tag)


channel.basic_consume(queue='receiver1', on_message_callback=callback)
while True:
    connection.process_data_events()

我希望在第32行上运行connection.process_data_events()时,会弹出新消息,并会调用inner_callback,但这只是在我首先执行ch.basic_ack时发生的。

最后,在这里真的需要建立新的连接吗?或者我在这段代码中缺少什么?此外,例如,如果任何微服务崩溃,我都会使用prefetch_count = 1来避免丢失消息,但是也许我在此prefetch_count中也缺少一些东西。

谢谢, 罗伯托

0 个答案:

没有答案