Skip to main content
 首页 » 编程设计

queue之RabbitMQ之消息传递顺序

2024年05月10日20powertoolsteam

我需要为我的新项目选择一个新的队列代理。

这次我需要一个支持发布/订阅的可扩展队列,并且必须保持消息排序。

我读到亚历克西斯评论:他写道:

"Indeed, we think RabbitMQ provides stronger ordering than Kafka"

我阅读了rabbitmq文档中的消息排序部分:

"Messages can be returned to the queue using AMQP methods that feature a requeue parameter (basic.recover, basic.reject and basic.nack), or due to a channel closing while holding unacknowledged messages...With release 2.7.0 and later it is still possible for individual consumers to observe messages out of order if the queue has multiple subscribers. This is due to the actions of other subscribers who may requeue messages. From the perspective of the queue the messages are always held in the publication order."

如果我需要按顺序处理消息,我只能使用rabbitMQ,每个消费者都有一个独占队列?

RabbitMQ 仍然被认为是有序消息队列的良好解决方案吗?

请您参考如下方法:

好吧,让我们仔细看看您上面描述的场景。我认为粘贴the documentation很重要紧接在问题中的代码片段之前以提供上下文:

Section 4.7 of the AMQP 0-9-1 core specification explains the conditions under which ordering is guaranteed: messages published in one channel, passing through one exchange and one queue and one outgoing channel will be received in the same order that they were sent. RabbitMQ offers stronger guarantees since release 2.7.0.

Messages can be returned to the queue using AMQP methods that feature a requeue parameter (basic.recover, basic.reject and basic.nack), or due to a channel closing while holding unacknowledged messages. Any of these scenarios caused messages to be requeued at the back of the queue for RabbitMQ releases earlier than 2.7.0. From RabbitMQ release 2.7.0, messages are always held in the queue in publication order, even in the presence of requeueing or channel closure. (emphasis added)

因此,很明显,从 2.7.0 开始,RabbitMQ 在消息排序方面对原始 AMQP 规范进行了相当大的改进。

对于多个(并行)消费者,无法保证处理顺序。
第三段(粘贴在问题中)继续给出免责声明,我将其解释为:“如果队列中有多个处理器,则不再保证消息将按顺序处理。”他们在这里所说的只是 RabbitMQ 不能违背数学定律。

考虑银行里的一排顾客。这家银行以按照客户进入银行的顺序为他们提供帮助而自豪。顾客排队,并由 3 个可用柜员中的下一个提供服务。

今天早上,碰巧三个柜员同时都有空,接下来的 3 位顾客也过来了。突然,三个柜员中的第一个得了重病,无法完成对队列中第一个顾客的服务。此时,柜员 2 已经结束了对顾客 2 的服务,柜员 3 也已经开始为顾客 3 提供服务。

现在,可能会发生以下两种情况之一。 (1) 排队的第一个顾客可以回到队伍的前面,或者 (2) 第一个顾客可以抢占第三个顾客,导致柜员停止为第三个顾客工作并开始为第一个顾客工作。 RabbitMQ 和我所知道的任何其他消息代理都不支持这种类型的抢占逻辑。无论哪种情况,第一个顾客实际上并没有首先得到帮助——第二个顾客却得到了帮助,因为他足够幸运,很快就找到了一位优秀、快速的出纳员。保证客户得到有序帮助的唯一方法是由一名柜员一次帮助一名客户,这会给银行带来重大的客户服务问题。

鉴于您有多个消费者,不可能确保在每种可能的情况下都按顺序处理消息。如果您有多个队列、多个独占消费者、不同的代理等,这并不重要 - 无法先验地保证多个消费者按顺序应答消息。但 RabbitMQ 会尽最大努力。