RabbitMQ 批量确认
RabbitMQ Batch Ack
我对 rabbitmq 如何处理批处理确认有疑问。我知道 Prefetch 值是在达到其限制之前将排队的最大消息数。但是,我不确定 ack 是自己管理还是我必须在代码中管理它。
哪种方法正确?
发送每个 basicAck 并将 multiple 设置为 true
或
等到应该发送 10 个 ack 并只发送最后一个,AMQP 将自动发送队列中的所有前一个。 (多个设置为真)
关于 Prefetch value is the max number of messages that will get queued before reaching its limit.
的第一个更正 - 这不是预取值;预取值是消费者 "gets" 来自队列的 UN-ACKed 消息的数量。所以他们有点被分配给消费者,但在他们被确认之前一直留在队列中。引用自 here,当 prefetch 为 1
This tells RabbitMQ not to give more than one message to a worker at a
time. Or, in other words, don't dispatch a new message to a worker
until it has processed and acknowledged the previous one.
对于你的问题:
I wasn't sure if the ack's manage themselves or if I have to manage
this in code.
您可以将自动确认标志设置为真,然后您可以说 the ack's manage themselves
TL;DR multiple = true 在某些情况下更快,但需要更仔细的簿记和批处理要求
消费者收到的消息具有特定于该消费者的单调增长的 ID。 id 是一个 64 位数字(它实际上可能是一个无符号的 32 位,但因为 Java 没有它的长)称为交付标签。预取是消费者将收到的未确认的最多消息。
当您确认具有多个 true
的最高交付标签时,它将确认消费者未完成的具有较低交付标签(较小数字)的所有未确认消息。显然,如果你有高预取,这比确认每条消息要快。
现在 RabbitMQ 知道消费者收到了消息(未确认的消息),但它不知道是否所有这些消息都已正确使用。因此,开发人员有责任确保之前的所有消息都已被使用。消费者将按顺序传递消息(我相信客户端在内部使用 BlockingQueue)但取决于 library/client 在下游使用的消息可能不会。
因此,这仅在您一次将消息批量处理(例如事务或将一组消息发送到其他系统)或可靠地缓冲时才有效。这通常是通过阻塞队列完成的,然后定期清空队列以将一组消息发送到下游系统。
另一方面,如果您实时传输每条消息,那么您就无法真正做到这一点(即 multiple = false)。
还有一种情况是,其中一条消息在组中是错误的(例如,从内部队列中删除...而不是兔子队列)并且您不会拒绝那个错误的消息。如果是这种情况,您也不能使用 multiple = true
。
最后,如果您等待一定数量的消息(而不是说时间)超过预取,您将无限期地等待....这不是一个好主意。您需要按时等待,消息数量必须 <=
预取。
如您所见,正确使用 multiple = true
.
非常重要
我对 rabbitmq 如何处理批处理确认有疑问。我知道 Prefetch 值是在达到其限制之前将排队的最大消息数。但是,我不确定 ack 是自己管理还是我必须在代码中管理它。
哪种方法正确?
发送每个 basicAck 并将 multiple 设置为 true
或
等到应该发送 10 个 ack 并只发送最后一个,AMQP 将自动发送队列中的所有前一个。 (多个设置为真)
关于 Prefetch value is the max number of messages that will get queued before reaching its limit.
的第一个更正 - 这不是预取值;预取值是消费者 "gets" 来自队列的 UN-ACKed 消息的数量。所以他们有点被分配给消费者,但在他们被确认之前一直留在队列中。引用自 here,当 prefetch 为 1
This tells RabbitMQ not to give more than one message to a worker at a time. Or, in other words, don't dispatch a new message to a worker until it has processed and acknowledged the previous one.
对于你的问题:
I wasn't sure if the ack's manage themselves or if I have to manage this in code.
您可以将自动确认标志设置为真,然后您可以说 the ack's manage themselves
TL;DR multiple = true 在某些情况下更快,但需要更仔细的簿记和批处理要求
消费者收到的消息具有特定于该消费者的单调增长的 ID。 id 是一个 64 位数字(它实际上可能是一个无符号的 32 位,但因为 Java 没有它的长)称为交付标签。预取是消费者将收到的未确认的最多消息。
当您确认具有多个 true
的最高交付标签时,它将确认消费者未完成的具有较低交付标签(较小数字)的所有未确认消息。显然,如果你有高预取,这比确认每条消息要快。
现在 RabbitMQ 知道消费者收到了消息(未确认的消息),但它不知道是否所有这些消息都已正确使用。因此,开发人员有责任确保之前的所有消息都已被使用。消费者将按顺序传递消息(我相信客户端在内部使用 BlockingQueue)但取决于 library/client 在下游使用的消息可能不会。
因此,这仅在您一次将消息批量处理(例如事务或将一组消息发送到其他系统)或可靠地缓冲时才有效。这通常是通过阻塞队列完成的,然后定期清空队列以将一组消息发送到下游系统。
另一方面,如果您实时传输每条消息,那么您就无法真正做到这一点(即 multiple = false)。
还有一种情况是,其中一条消息在组中是错误的(例如,从内部队列中删除...而不是兔子队列)并且您不会拒绝那个错误的消息。如果是这种情况,您也不能使用 multiple = true
。
最后,如果您等待一定数量的消息(而不是说时间)超过预取,您将无限期地等待....这不是一个好主意。您需要按时等待,消息数量必须 <=
预取。
如您所见,正确使用 multiple = true
.