Py学习  »  MQ

rabbitmq请求顺序

Maggyero • 5 年前 • 855 次点击  

根据Rabbitmq文档 Consumer Acknowledgements :

当消息被重新排队时,如果可能的话,它将被放在队列中的原始位置。如果不是(由于多个消费者共享一个队列时来自其他消费者的并发传递和确认),则消息将重新排队到靠近队列头的位置。

如果服务器队列最初是

尾部[C B A]头部

客户机使用者使用头消息(“A”),服务器队列应该变成:

尾部[Cb]头

然后,如果客户机使用者捕获处理过的消息,则消息应在头部的服务器队列中重新排队(根据文档,它的“原始位置”),服务器队列应变为:

尾部[C B A]头部

最后,客户机使用者应该再次使用相同的头消息(“A”)。

但这不是我使用python库pika观察到的。我观察到,nacked消息在服务器队列的尾部而不是在头部(原始位置)重新排队。rabbitmq文档正确还是库PIKA正确?

样例代码:

import logging

import pika

logging.basicConfig(level=logging.INFO)
logging.getLogger("pika").propagate = False
parameters = pika.ConnectionParameters()


# Produce messages

with pika.BlockingConnection(parameters) as connection:
    queue = "foobar"
    routing_key = queue
    channel = connection.channel()
    channel.queue_declare(queue=queue)

    for body in ["a", "b", "c"]:
        channel.publish(exchange="", routing_key=routing_key, body=body)
        logging.info("Produced message %r with routing key %r", body, routing_key)


# Consume messages

def handle(channel, method, properties, body):
    logging.info("Consumed message %r from queue %r", body.decode(), queue)
    channel.basic_nack(method.delivery_tag)


with pika.BlockingConnection(parameters) as connection:
    queue = "foobar"
    channel = connection.channel()
    channel.queue_declare(queue=queue)
    channel.basic_consume(queue=queue, on_message_callback=handle)
    channel.start_consuming()

输出:

信息:根:生成了带有路由键“foobar”的消息“a”
信息:根:生成了带有路由键“foobar”的消息“b”
信息:根:生成了带有路由键“foobar”的消息“c”
信息:根:已使用队列“foobar”中的消息“a”
信息:根:已使用队列“foobar”中的消息“b”
信息:根:已使用队列“foobar”中的消息“c”
信息:根:已使用队列“foobar”中的消息“a”
信息:根:已使用队列“foobar”中的消息“b”
信息:根:已使用队列“foobar”中的消息“c”
信息:根:已使用队列“foobar”中的消息“a”
信息:根:已使用队列“foobar”中的消息“b”
信息:根:已使用队列“foobar”中的消息“c”

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/30887
 
855 次点击  
文章 [ 2 ]  |  最新文章 5 年前
Maggyero
Reply   •   1 楼
Maggyero    5 年前

谢谢你@olivier。用 channel.basic_qos(prefetch_count=1) 我得到记录在案的行为:

信息:根:生成了带有路由键“foobar”的消息“a”
信息:根:生成了带有路由键“foobar”的消息“b”
信息:根:生成了带有路由键“foobar”的消息“c”
信息:根:已使用队列“foobar”中的消息“a”
信息:根:已使用队列“foobar”中的消息“a”
信息:根:已使用队列“foobar”中的消息“a”
信息:根:已使用队列“foobar”中的消息“a”
信息:根:已使用队列“foobar”中的消息“a”
信息:根:已使用队列“foobar”中的消息“a”
信息:根:已使用队列“foobar”中的消息“a”
信息:根:已使用队列“foobar”中的消息“a”
信息:根:已使用队列“foobar”中的消息“a”

Olivier
Reply   •   2 楼
Olivier    5 年前

您遇到的行为很可能是由于预取行为。

由于您没有具体说明所需的服务质量,我相信(如果您能提供一个知识更丰富的信息来源来确认这一点,我会很感激吗?)预取由服务器决定,可能会非常高。

其思想是,对于性能问题,客户机可以获得多条消息,这在大多数情况下都是有利的:

  • 如果用户端有多线程,那么他可能能够并行处理多个消息,因此在给定的时间内有多个消息尚未打包。
  • 为了在“快乐”的情况下进行更流畅的处理,客户机可以对一个消息块进行ACK,让服务器知道,在给定的消息之前,客户机接收到的所有消息都是ACK,当我们有大量需要很少处理的消息的情况时,它减少了开销。

如果检查下面的文档链接,它们将解释如何控制行为。

有关这些点的其他信息,请访问: