RabbitMQ中的immediate和mandatory标志的使用

63

我正在使用RabbitMQ服务器。

对于发布消息,我将immediate字段设置为true并尝试发送50,000条消息。使用rabbitmqctl list_queues命令,我发现队列中的消息数量为

然后,我将immediate标志更改为false,再次尝试发送50,000条消息。使用rabbitmqctl list_queues命令,我发现队列中共有100,000条消息(目前没有消费者存在)。

之后,我启动了一个消费者,它消费了所有100,000条消息。

请问有人可以帮我理解immediate比特字段以及这种行为吗?此外,我也无法理解mandatory比特字段的概念。

2个回答

143
immediatemandatory 字段是 AMQP 规范的一部分,并且在 RabbitMQ FAQ 中有相关解释来澄清它们的含义:

Mandatory

该标志告诉服务器如何处理无法将消息路由到队列的情况。具体地说,如果设置了 mandatory 并在运行绑定后将消息放置在零个队列上,则将消息返回给发送方(使用 basic.return)。如果在同样的情况下没有设置 mandatory,则服务器将默默丢弃消息。

或者用我的话说,"将此消息放入至少一个队列中。如果无法这样做,请将其退回给我。"

Immediate

对于设置了 immediate 的发布消息,如果匹配的队列有已准备好的消费者,则其中一个消费者将路由该消息。如果幸运的消费者在确认接收之前崩溃,则该消息将被重新排队和/或传递到该队列上的其他消费者(如果没有崩溃,则确认接收消息并按正常方式完成所有操作)。然而,如果匹配的队列没有准备好的消费者,则不会将该消息排队以便从该队列进行后续重新传递。只有当所有匹配的队列都没有准备好的消费者时,才会将该消息返回给发送方(通过 basic.return)。

或者用我的话说,"如果至少有一个连接到我的队列并可以立即接收消息的消费者,请立即将此消息投递给他们。如果没有连接的消费者,则没有理由让我的消息稍后被消费,因为他们永远不会看到它。他们睡觉,他们错过了。"


2
如果幸运的消费者在确认收据之前崩溃,并且队列中没有其他消费者,会发生什么?消息是否仍然停留在队列中?还是会被退回? - nornagon
我没有测试过,但我可以猜测,崩溃的消费者是另一回事,它的行为与重新入队或死信相关。 - Shay Tsadok
很抱歉五年后才添加评论...在我看来,immediate标志在RabbitMQ的API中没有暴露出来?至少在.Net API中没有。我发现唯一可以设置immediate标志的方法是通过一个内部的BasicPublish类的构造函数,但该构造函数在库中从未被使用。immediate是否已经被弃用或不建议使用? - Niall Connaughton
13
我找到了我的问题的答案:Rabbit v3.0中已删除了immediate,因为它很少被使用,使代码复杂化并有替代方案。 - Niall Connaughton
3
喜欢那句话“或者以我的话说”。我希望所有的技术规格书都像这样,简明易懂。 :) - Anand

17

http://www.rabbitmq.com/blog/2012/11/19/breaking-things-with-rabbitmq-3-0/

移除“immediate”标志

有什么变化?我们移除了AMQP的basic.publish上很少使用的"immediate"标志的支持。

你为什么这么做?"immediate"的支持使得代码库的许多部分变得更加复杂,特别是在镜像队列方面。 它也妨碍了我们在镜像队列中实现重大性能改进。

我需要做什么?如果你只想发布消息,如果它们立即不被消费就会被删除,那么你可以将其发布到TTL为0的队列。

如果您还需要使发布者能够确定发生了什么,您还可以使用DLX功能将此类消息路由到另一个队列,从中发布者可以消费它们。

这里只是简单地复制公告以供参考。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接