【整理】RabbitMQ publish方法中的immediate和mandatory属性

简介:


      鉴于在 RabbitMQ 的使用过程中,很多同学搞不清楚 basic.publish 接口中 mandatory 和 immediate 的背后含义,特搜集整理网上相关文章,以便彻底理解该问题。

===== 我是三体分隔线 =====  

在 RabbitMQ 3.0.0 版本的  README   中如是说:  
?
1
2
3
4
...
feature removal
23896 remove support for AMQP's "immediate" publish mode
...
另外一篇   文章   中也对该变更进行了说明  
?
1
2
3
4
5
6
7
8
9
10
11
12
Removal of "immediate" flag
What changed? We removed support for the rarely-used "immediate" flag on AMQP's basic.publish.
 
Why on earth did you do that? Support for "immediate" made many parts of the codebase more complex,
particularly around mirrored queues. It also stood in the way of our being able to deliver
substantial performance improvements in mirrored queues.
 
What do I need to do ? If you just want to be able to publish messages that will be dropped if they
are not consumed immediately, you can publish to a queue with a TTL of 0.
 
If you also need your publisher to be able to determine that this has happened, you can also use the
DLX feature to route such messages to another queue, from which the publisher can consume them.
RabbitMQ 官网上针对 AMQP-0-9-1 协议中 basic.publish 方法的说明  
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
...publish(short reserved-1, exchange-name exchange, shortstr routing-key, bit mandatory, bit immediate)
...
bit mandatory
This flag tells the server how to react if the message cannot be routed to a queue. If this flag is set ,
the server will return an unroutable message with a Return method. If this flag is zero, the server
silently drops the message.
The server SHOULD implement the mandatory flag.
 
bit immediate
This flag tells the server how to react if the message cannot be routed to a queue consumer immediately.
If this flag is set , the server will return an undeliverable message with a Return method. If this flag
is zero, the server will queue the message, but with no guarantee that it will ever be consumed.
The server SHOULD implement the immediate flag.
...

下面是网上找到的   关于 mandatory 和 immediate 两个属性的讨论    

AMQP's basic.publish method has two flags - mandatory and immediate - that trigger checks at the server and result in messages getting returned to clients with basic.return when the necessary conditions aren't met. See http://www.rabbitmq.com/amqp-0-9-1-reference.html#basic.publish for the details. I can just about see why 'mandatory' may be useful, but 'immediate' has always struck me as a bizarre and I fear that anybody using it may well do so w/o fully understanding the semantics - can't blame them, it *is* bizarre. Because of that, and since it complicates the code in many places, we are considering dropping support for 'immediate'. So is anybody actually using the 'immediate' flag?
I'd support this move. Have never used "immediate".
Just curious, are there any benefits for removing it -- is it preventing / complicating support for other features?
Yes. It accounts for a fair bit logic scattered across the code base and we've just found another case where in order to significantly improve performance of mirrored queues we'd have to make yet more code aware of the 'immediate' flag.
Well, the specific thing that we've bumped into in this case is that support for immediate is greatly slowing down HA queues. We could be smarter about this, at the cost of tangling the code further. So if we want to make HA queues faster (and we do!) we can either keep immediate and add a bunch of code at the same time, or remove immediate and delete a bunch of code. There are quite a number of places where we have notably greater complexity just to support this weird feature that (we suspect) no-one uses. It just feels very disproportionate.
Matthias / Simon, thanks for the background. I'm not using the immediate flag, but I've considered using it.   Admittedly, I'm not fully aware of exactly how it works. It would be helpful to have a better understanding of the semantics. Can you explain what the publisher is notified of (if anything?) when there are 10 queues bound to an exchange named HighPriority, a message with immediate flag true is published to HighPriority, and 7 out of the 10 queues have the message consumed immediately.
No notification is sent to the publisher in that case. A basic.return is only sent if *no* queues were able to send the message to a consumer immediately.
Here are a few more warts about 'immediate':
- while a message might get sent out to a consumer straight away, there is of course no guarantee that such a message will reach the consumer, get processed and ack'ed. If any of these steps go wrong the message will end up in the queue (unless the consuming happened with no-ack, in which case it is simply lost), even though supposedly it was delivered immediately.
- a queue can have a consumer and yet 'immediate' delivery may fail (and a basic.return issued) because: a) the consumer isn't quick enough and a backlog of messages has built up, b) the consumer has configured a 'basic.qos' prefetch count and that the limit has been reached
- the interaction with transactions is not at all obvious. This does apply to 'mandatory' too though. See http://www.rabbitmq.com/semantics.html#tx
Matthias, thanks for the explanation. Considering your points below, I now have a better understanding on your thought that the actual use-cases and practicality to publish messages with the immediate flag are minimal. In light of the details, I won't be using it -- faster mirrored queues sounds better to me. :o)
Couldn't it be possible emulate immediate by delivering to a TTL'ed queue, then having a dead-letter queue that the publisher consumes from to be notified that a message has not been consumed?
Yes. It's not an exact emulation, but arguably more flexible, e.g. it gives greater control over how the 'returned' messages are dealt with.
Plus 1 for faster HA queues and less complexity in the code base.

下面是    stackoverflow 上关于上述两个属性的讨论  
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
The immediate and mandatory fields are part of the AMQP specification, and are also covered in the
RabbitMQ FAQ to clarify how its implementers interpreted their meaning:
 
Mandatory
This flag tells the server how to react if a message cannot be routed to a queue. Specifically, if
mandatory is set and after running the bindings the message was placed on zero queues then the message
is returned to the sender (with a basic. return ). If mandatory had not been set under the same
circumstances the server would silently drop the message.
 
Or in my words, "Put this message on at least one queue. If you can't, send it back to me."
 
Immediate
For a message published with immediate set , if a matching queue has ready consumers then one of them
will have the message routed to it. If the lucky consumer crashes before ack'ing receipt the message
will be requeued and /or delivered to other consumers on that queue ( if there's no crash the messaged
is ack 'ed and it' s all done as per normal). If, however, a matching queue has zero ready consumers the
message will not be enqueued for subsequent redelivery on from that queue. Only if all of the matching
queues have no ready consumers that the message is returned to the sender (via basic. return ).
 
Or in my words, "If there is at least one consumer connected to my queue that can take delivery of a
message right this moment, deliver this message to them immediately. If there are no consumers connected
then there 's no point in having my message consumed later and they' ll never see it. They snooze, they lose."
最后给出两篇中文说明,可以帮助理解:  

RabbitMQ(二)AMQP协议mandatory和immediate标志位区别  
RabbitMQ(四)RabbitMQ死信邮箱(DLX)  
相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
1月前
|
存储 Ubuntu 安全
在Ubuntu 16.04上安装和保护Mosquitto MQTT消息代理的方法
在Ubuntu 16.04上安装和保护Mosquitto MQTT消息代理的方法
38 1
|
1月前
|
消息中间件 存储 Ubuntu
简单记录一下常规安装 RabbitMQ 的方法步骤
这篇文章详细介绍了在本地环境下安装和配置RabbitMQ消息队列的过程,包括RabbitMQ的基本概念、安装步骤、不同模式的特点以及在Linux和Windows系统下的安装方法。
21 0
EMQ
|
4月前
|
JSON Linux 网络性能优化
MQTT 5.0 报文解析 02:PUBLISH 与 PUBACK
本文将介绍在 MQTT 中用于传递应用消息的 PUBLISH 报文以及它的响应报文。不管是客户端向服务端发布消息,还是服务端向订阅端转发消息,都需要使用 PUBLISH 报文。决定消息流向的主题、消息的实际内容和 QoS 等级,都包含在 PUBLISH 报文中。
EMQ
188 6
MQTT 5.0 报文解析 02:PUBLISH 与 PUBACK
|
消息中间件 存储 Java
【RabbitMQ四】——RabbitMQ发布订阅模式(Publish/Subscribe)
【RabbitMQ四】——RabbitMQ发布订阅模式(Publish/Subscribe)
318 1
|
消息中间件
RabbitMQ之mandatory和immediate
mandatory和immediate是AMQP协议中basic.publish方法中的两个标识位,它们都有当消息传递过程中不可达目的地时将消息返回给生产者的功能。对于刚开始接触RabbitMQ的朋友特别容易被这两个参数搞混,这里博主整理了写资料,简单讲解下这两个标识位。
144 0
|
4月前
MQTT的心跳保活机制是通过`setKeepAliveInterval()`方法设置的
MQTT的心跳保活机制是通过`setKeepAliveInterval()`方法设置的
626 2
|
存储 消息中间件 RocketMQ
RocketMQ中MessageExt属性
RocketMQ中MessageExt属性
232 0
|
11月前
|
消息中间件 存储 算法
RabbitMQ之Queue(队列)属性解读
RabbitMQ之Queue(队列)属性解读
|
11月前
|
消息中间件 存储 Java
RabbitMQ之Exchange(交换机)属性及备用交换机解读
RabbitMQ之Exchange(交换机)属性及备用交换机解读
|
网络协议 Android开发 数据安全/隐私保护
HarmonyOS系统中内核实现MQTT协议开发的方法
大家好,今天主要来聊一聊,如何使用鸿蒙开始实现MQTT协议开发的方法
309 1
HarmonyOS系统中内核实现MQTT协议开发的方法