博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【整理】RabbitMQ publish方法中的immediate和mandatory属性
阅读量:6214 次
发布时间:2019-06-21

本文共 7245 字,大约阅读时间需要 24 分钟。

hot3.png

      鉴于在 RabbitMQ 的使用过程中,很多同学搞不清楚 basic.publish 接口中 mandatory 和 immediate 的背后含义,特搜集整理网上相关文章,以便彻底理解该问题。
===== 我是三体分隔线 =====
在 RabbitMQ 3.0.0 版本的
中如是说:
...feature removal23896 remove support for AMQP's "immediate" publish mode...
另外一篇
中也对该变更进行了说明
Removal of "immediate" flagWhat 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 官网上
...publish(short reserved-1, exchange-name exchange, shortstr routing-key, bit mandatory, bit immediate)...bit mandatoryThis 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 immediateThis 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....
下面是网上找到的
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.
下面是 
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:MandatoryThis 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."ImmediateFor 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."
最后给出两篇中文说明,可以帮助理解:

转载于:https://my.oschina.net/moooofly/blog/384969

你可能感兴趣的文章
#内存管理的艺术# 之 Nginx slab的实现 --- 第四篇“基于块的内存释放”
查看>>
linux下select函数详解及实例
查看>>
关于IE浏览器缓存的处理
查看>>
centos通过screen命令恢复xshell
查看>>
阿里联袂SMG,共同打造中式华尔街日报
查看>>
tr命令详解
查看>>
基于DRBD构建高可用主从MySQL服务器
查看>>
Python之匿名函数
查看>>
5-puppet软件包管理
查看>>
Linux下使用l7-filter过滤QQ、迅雷、电驴等
查看>>
总目录
查看>>
开源的感觉可用的 web 下拉组件
查看>>
NFS服务配置笔记
查看>>
Oracle ERP 技术探讨
查看>>
Java 通过JDBC连接Mysql数据库的方法和实例【图文说明】
查看>>
华为3Com建设安徽大学万兆校园网络案例
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
mysql 报错ERROR 1820 (HY000):You must resetpassword
查看>>
JSP中的request,session,application生命周期
查看>>