rabbitmq.“消费端确认收到”和“推送者确认”(5)

发布者的否定应答

    特殊情况下,中转服务节点无法成功的处理消息,则发送basic.nack消息,而不是basic.ack。这种情况下,basic.nack和basic.ack字段意义相同,都应重排字段都应被忽略。否定应答一个或多个消息,中转节点既声明无法处理这些消息,也不对这些消息再负责,基于这点客户端可能选择重新发布这些消息。
     在通道设置未确认模式,所有后到的消息将一次应答。不保证需要多久进行应答。同一个消息不会同时出现肯定和否定应答。
      basic.nack只有在队列对应的Erlang进程内部错误的时候才会发送。

推送的消息什么时候会被确认呢?

     对于无法路由到的消息,一旦exchange确认没有队列可以路由,中转节点就会发送一次确认信息。如果是强制发布的消息,客户端将在basic.ack前获取basic.return。对于否定应答(basic.nack)也是如此。
    对于可路由的消息,一旦消息被队列接受机会发送basic.ack。对于持久话的消息路由到持久话队列,这意味这持久话到硬盘。对于镜像队列,意味着所有的队列接受了这个消息。

持久化消息的应答延迟

     对于持久化消息,在消息持久化到硬盘之后才会发送basic.ack。RabbitMQ分批处理或者队列空闲的时候进行持久化,以最小化fsync的次数。这意味这个稳定的负载下,basic.ack要延迟数百毫秒发出。为了减轻系统的负载,最好进行异步处理应答、分批的推送消息或者等待确认消息。不同的客户端API会有差异。

消息发布者的确认消息的排序考虑

    通常情况,RabbitMQ以消息推送来的顺序向推送者进行确认。但是推送应答是异步发送的,可以确认一个或者一组消息。实际的情况,确认信息发布依赖消息的模式(事务、持久化)和消息所处队列属性。也就是说,不同的消息可视为在不同的时间应答。者以为者,相对于消息的书序,应答顺序可能不同。可能的活,应用不应该依赖应答的顺序。

推送应答和可保证传递

     如果写入磁盘前crash,服务端将丢失需要持久话的消息。
一些情况,者会导致服务端以费正常的行为。
举例,考虑这种场景:
1.客户端推送一个持久化消息到持久化队列
2.一个客户端从队列消费这个信息(注意消息和队列是持久化的),但是还未应答这个消息
3.服务端挂掉重启了
4.客户端重新连接上,并开始消费信息
    此时,客户端可以假设消息会重新传递是合理的。这不是:重启导致服务端丢失了消息。为了保证消息的持久化,客户端应该进行确认。如果channel已经在确认模式,推送者不是必须获取到丢失消息的英达信息(因为已经写入磁盘了)。

限制 传递标签的最大值

     标签是64位的值,最大值是9223372036854775807。由于标签的作用域是channel,消费者和生产者不可能用尽这个值。

原文:

Negative Acknowledgments for Publishes

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.

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.

basic.nack will only be delivered if an internal error occurs in the Erlang process responsible for a queue.

When Will Published Messages Be Confirmed by the Broker?

For unroutable messages, the broker will issue a confirm once the exchange verifies a message won't route to any queue (returns an empty list of queues). If the message is also published as mandatory, the basic.return is sent to the client before basic.ack. The same is true for negative acknowledgements (basic.nack).

For routable messages, the basic.ack is sent when a message has been accepted by all the queues. For persistent messages routed to durable queues, this means persisting to disk. For mirrored queues, this means that all mirrors have accepted the message.

Ack Latency for Persistent Messages

basic.ack for a persistent message routed to a durable queue will be sent after persisting the message to disk. The RabbitMQ message store persists messages to disk in batches after an interval (a few hundred milliseconds) to minimise the number of fsync(2) calls, or when a queue is idle. This means that under a constant load, latency for basic.ack can reach a few hundred milliseconds. To improve throughput, applications are strongly advised to process acknowledgements asynchronously (as a stream) or publish batches of messages and wait for outstanding confirms. The exact API for this varies between client libraries.

Ordering Considerations for Publisher Confirms

In most cases, RabbitMQ will acknowledge messages to publishers in the same order they were published (this applies for messages published on a single channel). However, publisher acknowledgements are emitted asynchronously and can confirm a single message or a group of messages. The exact moment when a confirm is emitted depends on the delivery mode of a message (persistent vs. transient) and the properties of the queue(s) the message was routed to (see above). Which is to say that different messages can be considered ready for acknowledgement at different times. This means that acknowledgements can arrive in a different order compared to their respective messages. Applications should not depend on the order of acknowledgements when possible.

Publisher Confirms and Guaranteed Delivery

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.

For instance, consider this scenario:

  1. a client publishes a persistent message to a durable 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,
  3. the broker dies and is restarted, and
  4. the client reconnects and starts consuming messages.

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 message hadn't been written to disk yet).

 

Limitations

 

Maximum Delivery Tag

Delivery tag is a 64 bit long value, and thus its maximum value is 9223372036854775807. Since delivery tags are scoped per channel, it is very unlikely that a publisher or consumer will run over this value in practice.

    

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值