文章目录
前言
基于官方文档https://www.rabbitmq.com/confirms.html,根据阅读习惯重新组织标题与内容,对RabbitMQ的消息确认机制进行说明。
定义
Delivery processing acknowledgements from consumers to RabbitMQ are known as acknowledgements in messaging protocols; broker acknowledgements to publishers are a protocol extension called publisher confirms. Both features build on the same idea and are inspired by TCP.
消费者向RabbitMQ进行消息delivery的确认称为acknowledgements,broker向生产者的确认称为publisher confirms。
Acknowledgements in delivery
Before we proceed to discuss other topics it is important to explain how deliveries are identified (and acknowledgements indicate their respective deliveries). When a consumer (subscription) is registered, messages will be delivered (pushed) by RabbitMQ using the
basic.deliver
method. The method carries a delivery tag, which uniquely identifies the delivery on a channel. Delivery tags are therefore scoped per channel.Delivery tags are monotonically growing positive integers and are presented as such by client libraries. Client library methods that acknowledge deliveries take a delivery tag as an argument.
Because delivery tags are scoped per channel, deliveries must be acknowledged on the same channel they were received on. Acknowledging on a different channel will result in an “unknown delivery tag” protocol exception and close the channel.
当消费者完成注册时,消息将会被basic.deliver
方法delivery,这个方法会携带一个在channel内的唯一标识这次delivery的delivery tag。它是单调递增的正整数,客户端库的方法在ack时会将其作为参数。由于delivery tag作用域仅限定为channel内,ack不同的channel将触发"unknown delivery tag"异常并关闭channel。
Depending on the acknowledgement mode used, RabbitMQ can consider a message to be successfully delivered either immediately after it is sent out (written to a TCP socket) or when an explicit (“manual”) client acknowledgement is received.
使用的ack模式不同,会影响RabbitMQ对消息是否成功delivery的定义——发送成功即认为成功(自动ack模式),或者,收到客户端的手动ack才认为成功(手动ack模式)。
自动ack模式
In automatic acknowledgement mode, a message is considered to be successfully delivered immediately after it is sent. This mode trades off higher throughput (as long as the consumers can keep up) for reduced safety of delivery and consumer processing. This mode is often referred to as “fire-and-forget”. Unlike with manual acknowledgement model, if consumers’s TCP connection or channel is closed before successful delivery, the message sent by the server will be lost. Therefore, automatic message acknowledgement should be considered unsafe and not suitable for all workloads.
自动ack模式中,消息在发送后就立即被认为成功交付,这种被称为"fire-and-forget"的模式通过降低安全性来获得更高的性能。需要注意的是,使用这种模式是不安全的,可能会导致消息丢失。
Another thing that’s important to consider when using automatic acknowledgement mode is consumer overload. Manual acknowledgement mode is typically used with a bounded channel prefetch which limits the number of outstanding (“in progress”) deliveries on a channel. With automatic acknowledgements, however, there is no such limit by definition. Consumers therefore can be overwhelmed by the rate of deliveries, potentially accumulating a backlog in memory and running out of heap or getting their process terminated by the OS. Some client libraries will apply TCP back pressure (stop reading from the socket until the backlog of unprocessed deliveries drops beyond a certain limit). Automatic acknowledgement mode is therefore only recommended for consumers that can process deliveries efficiently and at a steady rate.
使用自动ack模式需要注意的另一点是消费负载。手动ack模式通常用于有界channel的预处理,这限制了待处理的交付数量,而自动ack没有定义这个限制,消费者可能被交付率淹没导致大量积压,从而耗尽资源或导致操作系统终止其进程。某些客户端库使用TCP背压机制来解决这一问题。自动ack模式建议仅由能够高效、稳定消费的消费者使用。
手动ack模式
Manually sent acknowledgements can be positive or negative and use one of the following protocol methods:
basic.ack
is used for positive ackn