仓库源文站点原文


title: "RabbitMQ 消息确认机制" categories: Tech updated: comments: true

mathjax: false

生产者先把消息发到 exchange (很多个), exchange 决定把消息分发到哪些 queue (很多个), 再从 queue 发到消费者.

确认机制分为两部分, exchange 确认收到 publisher 的消息, consumer 确认收到 queue 的消息. 来自官方文档 Consumer Acknowledgements and Publisher Confirms — RabbitMQ

<!-- more -->

(Consumer) Delivery Acknowledgements

消费者向 RabbitMQ 发 ack 有两种时机

Delivery Identifiers: Delivery Tags

The below explains how deliveries are identified (and acknowledgements indicate their respective deliveries). When a consumer is registered, messages will be delivered by RabbitMQ using the basic.deliver method. The method carries a delivery tag (单调递增的整数, 为 ack 的一个参数), which uniquely identifies the delivery on a channel. Delivery tags are therefore scoped per channel. 所以要在同一 channel 操作.

Consumer Acknowledgement Modes and Data Safety Considerations

Depending on the acknowledgement mode used, RabbitMQ can consider a message to be successfully delivered either

Negative Acknowledgement and Requeuing of Deliveries

有时当前消费者没法立刻处理消息, 可以用 basic.nack

<font color="lightgrey">When a message is requeued, it will be placed to its original position in its queue, if possible. If not, the message will be requeued to a position closer to queue head.</font>

手动模式下, 任何没有 ack 的消息在 channel 关闭后会自动 requeue. 因此消费者需要处理重新分发或者保证操作幂等性.

<font color="lightgrey">Channel 关闭的场景包括 TCP connection loss by clients, consumer application failures, and channel-level protocol exceptions.</font>

Consumer Acknowledgement Modes, Prefetch and Throughput

Ack 模式和 prefetch count 影响消费者的吞吐量. 自动 ack + 提高 prefetch count 可以提高吞吐量, 但是导致消费者占用更多 RAM.

The "prefetch count" value in the basic.qos (qos stands for quality of service) method defines the max number of unacknowledged deliveries that are permitted on a channel.

Values in the 100 through 300 range usually offer optimal throughput and do not run significant risk of overwhelming consumers. Higher values often run into the law of diminishing returns.

Publisher Confirms

在标准的 AMQP 0-9-1 下, 确保消息可靠的唯一方式是用事务 (事务模式), 但这会让吞吐量锐减为 1/250. 因此引入确认机制 (确认模式), 和消费者确认机制类似.

<font color="lightgrey">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 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. </font>

Negative Acknowledgments for Publishes

basic.nack will only be delivered if an internal error occurs. 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.

剩下的从 confirms.html#when-publishes-are-confirmed 开始看.

备考杂项