`

publish消息确认

 
阅读更多
Using standard AMQP, the only way to guarantee that a message isn't lost is by using transactions -- make the channel transactional, publish the message, commit. In this case, transactions are unnecessarily heavyweight and decrease throughput by a factor of 250. To remedy this, a confirmation mechanism was introduced.
如果采用标准的 AMQP 协议,则唯一能够保证消息不会丢失的方式是利用事务机制 -- 令 channel 处于 transactional 模式、向其 publish 消息、执行 commit 动作。在这种方式下,事务机制会带来大量的多余开销,并会导致吞吐量下降 250% 。为了补救事务带来的问题,引入了 confirmation 机制(即 Publisher Confirm)。


To enable confirms, a client sends the confirm.select method. Depending on whether no-wait was set or not, the broker may respond with a confirm.select-ok. Once the confirm.select method is used on a channel, it is said to be in confirm mode. A transactional channel cannot be put into confirm mode and once a channel is in confirm mode, it cannot be made transactional.
为了使能 confirm 机制,client 首先要发送 confirm.select 方法帧。取决于是否设置了 no-wait 属性,broker 会相应的判定是否以 confirm.select-ok 进行应答。一旦在 channel 上使用 confirm.select方法,channel 就将处于 confirm 模式。处于 transactional 模式的 channel 不能再被设置成 confirm 模式,反之亦然。


Once a channel is in confirm mode, both the broker and the client count messages (counting starts at 1 on the first confirm.select). The broker then confirms messages as it handles them by sending a basic.ack on the same channel. The delivery-tag field contains the sequence number of the confirmed message. The broker may also set the multiple field in basic.ack to indicate that all messages up to and including the one with the sequence number have been handled.
一旦 channel 处于 confirm 模式,broker 和 client 都将启动消息计数(以 confirm.select 为基础从 1 开始计数)。broker 会在处理完消息后,在当前 channel 上通过发送 basic.ack 的方式对其进行 confirm 。delivery-tag 域的值标识了被 confirm 消息的序列号。broker 也可以通过设置 basic.ack 中的 multiple 域来表明到指定序列号为止的所有消息都已被 broker 正确的处理了。


In exceptional cases when the broker is unable to handle messages successfully, instead of a basic.ack, the broker will send a basic.nack. In this context, fields of the basic.nack have the same meaning as the corresponding ones in basic.ack and the requeue field should be ignored. By nack'ing one or more messages, the broker indicates that it was unable to process the messages and refuses responsibility for them; at that point, the client may choose to re-publish the messages.
在异常情况中,broker 将无法成功处理相应的消息,此时 broker 将发送 basic.nack 来代替 basic.ack 。在这个情形下,basic.nack 中各域值的含义与 basic.ack 中相应各域含义是相同的,同时 requeue 域的值应该被忽略。通过 nack 一或多条消息,broker 表明自身无法对相应消息完成处理,并拒绝为这些消息的处理负责。在这种情况下,client 可以选择将消息 re-publish 。


After a channel is put into confirm mode, all subsequently published messages will be confirmed or nack'd once. No guarantees are made as to how soon a message is confirmed. No message will be both confirmed and nack'd.
在 channel 被设置成 confirm 模式之后,所有被 publish 的后续消息都将被 confirm(即 ack) 或者被 nack 一次。但是没有对消息被 confirm 的快慢做任何保证,并且同一条消息不会既被 confirm 又被 nack 。


An example in Java that publishes a large number of messages to a channel in confirm mode and waits for the acknowledgements can be found here.
一个 Java 示例展现了 publish 大量消息到一个处于 confirm 模式的 channel 并等待获取 acknowledgement 的情况,示例在这里。




When will messages be confirmed?
消息会在何时被 confirm?


The broker will confirm messages once:
broker 将在下面的情况中对消息进行 confirm :
•it decides a message will not be routed to queues
(if the mandatory flag is set then the basic.return is sent first) or
broker 发现当前消息无法被路由到指定的 queues 中(如果设置了 mandatory 属性,则 broker 会先发送 basic.return)
•a transient message has reached all its queues (and mirrors) or
非持久属性的消息到达了其所应该到达的所有 queue 中(和镜像 queue 中)
•a persistent message has reached all its queues (and mirrors) and been persisted to disk (and fsynced) or
持久消息到达了其所应该到达的所有 queue 中(和镜像 queue 中),并被持久化到了磁盘(被 fsync)
•a persistent message has been consumed (and if necessary acknowledged) from all its queues
持久消息从其所在的所有 queue 中被 consume 了(如果必要则会被 acknowledge)



Notes


The broker loses persistent messages if it crashes before said messages are written to disk. Under certain conditions, this causes the broker to behave in surprising ways.
broker 会丢失持久化消息,如果 broker 在将上述消息写入磁盘前异常。在一定条件下,这种情况会导致 broker 以一种奇怪的方式运行。


For instance, consider this scenario:
例如,考虑下述情景:
1.a client publishes a persistent message to a durable queue
一个 client 将持久消息 publish 到持久 queue 中
2.a client consumes the message from the queue (noting that the message is persistent and the queue durable), but doesn't yet ack it,
另一个 client 从 queue 中 consume 消息(注意:该消息具有持久属性,并且 queue 是持久化的),当尚未对其进行 ack
3.the broker dies and is restarted, and
broker 异常重启
4.the client reconnects and starts consuming messages.
client 重连并开始 consume 消息

At this point, the client could reasonably assume that the message will be delivered again. This is not the case: the restart has caused the broker to lose the message. In order to guarantee persistence, a client should use confirms. If the publisher's channel had been in confirm mode, the publisher would  not  have received an ack for the lost message (since the consumer hadn't ack'd it and it hadn't been written to disk).

在上述情景下,client 有理由认为消息需要被(broker)重新 deliver 。但这并非事实:重启(有可能)会令 broker 丢失消息。为了确保持久性,client 应该使用 confirm 机制。如果 publisher 使用的 channel 被设置为 confirm 模式,publisher 将不会收到已丢失消息的 ack(这是因为 consumer 没有对消息进行 ack ,同时该消息也未被写入磁盘)。


参考:http://blog.csdn.net/jiao_fuyou/article/details/21594205

官网文档:http://www.rabbitmq.com/confirms.html

参考:http://www.cnblogs.com/leocook/p/mq_rabbitmq_2.html
分享到:
评论

相关推荐

    app.publish.rar|app.publish.rar

    在"标签"中提到了"nuget",这进一步确认了这个压缩包与NuGet包有关。NuGet服务器可以是本地的、私有的,也可以是公共的NuGet.org。私有服务器通常用于企业内部,以便安全地管理和分发组织内部的库和组件。 至于...

    How to Write and Publish a Scientific Paper

    标题对于吸引读者和确定论文主题具有重要作用,应简洁且能准确反映文章内容。标题中应避免使用缩写和行话,以确保读者易于理解。 9. 作者列表及其地址的准备(How to List the Authors and Addresses) 作者的排序...

    How to write publish a scientific paper

    【文件】"How To Write & Publish a Scientific Paper.jpg"可能是包含论文写作和发表流程的图表,"More Links.txt"可能是提供更多相关资源的链接,而"More Links.txt"可能是完整的PDF版指南,详细介绍了每一步的具体...

    NEWS_publish.rar_news publish

    【标题】"NEWS_publish.rar_news publish" 涉及的知识点主要集中在JSP(Java Server Pages)编程和新闻发布系统的实现。JSP是Java的一种动态网页技术,它允许开发人员在HTML页面中嵌入Java代码,以实现服务器端的...

    将消息写入消息队列

    - **消息确认**:消费者确认收到消息后,队列可以删除消息,防止重复处理。 6. 文件解析: - `将指令写入队列.sln`:这是一个Visual Studio解决方案文件,包含了项目和依赖关系的配置。 - `将指令写入队列.suo`...

    电商异步消息系统的实践

    常见的消息模型有发布/订阅(Publish/Subscribe, Pub/Sub)和点对点(Point-to-Point, P2P)。发布/订阅模型中,一个生产者发布消息,多个消费者可以订阅并接收消息;点对点模型则是一对一,每个消息仅被一个消费者...

    用消息队列实现的简单聊天程序

    此外,消息队列还可以通过消息确认机制确保消息的正确处理。 7. **负载均衡与扩展性**:消息队列可以连接多个服务器,实现负载均衡,当系统负载增加时,只需增加服务器数量,而无需修改客户端代码。 8. **代码实现...

    MQTTv3.1中文版

    - **消息类型**:指定了消息的类型,例如连接请求(CONNECT)、连接确认(CONNACK)等。 - **DUP标志**:用于标识消息是否是重复发送的。 - **QoS级别**:指示消息的服务质量级别。 - **RETAIN标志**:用于标识...

    JMS 教程 - 消息队列、消息服务

    **可靠性保障**:JMS提供多种级别的可靠性保障,允许开发者根据应用场景选择合适的消息确认策略,从而确保消息能够可靠地传递给目标消费者。 **消息持久化**:为了提高消息服务的可用性,JMS支持将消息持久化到磁盘...

    服务器消息服务

    7. **消息模型**:主要有两种模型——点对点(Point-to-Point)和发布/订阅(Publish/Subscribe)。点对点模型中,每个消息只有一个消费者;而在发布/订阅模型中,一个消息可以被多个订阅者消费。 8. **消息服务...

    QNX Persistent Publish/Subscribe Developer's Guide

    QNX是一款广泛应用于嵌入式系统的高级实时操作系统,以其高效、可靠和确定性的特性著称。在QNX系统中,发布/订阅模式是一种重要的通信方式,允许软件组件之间异步交换数据,而无需直接相互调用。 该指南的核心内容...

    消息队列入门项目demo

    JMS支持两种主要的消息模型:点对点(Point-to-Point,P2P)和发布/订阅(Publish/Subscribe,Pub/Sub)。 在点对点模型中,消息由一个生产者发送到一个称为队列的特定目的地,然后由一个或多个消费者接收。每个...

    7道消息队列ActiveMQ面试题!

    ActiveMQ提供了多种消息模式,包括点对点(Point-to-Point)和发布/订阅(Publish/Subscribe)模式。点对点模式中,消息生产者发送消息到队列,消费者从队列中拉取消息,消息在队列中仅能被一个消费者消费。在发布/...

    MQTT,基于TCP/IP协议的一种传输模式

    在QoS 2等级的PUBLISH消息中包含包唯一标识,发送者会一直将该消息当作“未确认”的消息,知道收到对应的PUBCOMP确认消息。 MQTT协议是一种基于发布-订阅模型的消息传递协议,具有小消息头、可靠的消息交付保证和...

Global site tag (gtag.js) - Google Analytics