我有一个关于rabbitmq如何处理批量确认的问题。我知道Prefetch值是在达到其限制之前将排队的最大消息数。但是,我不确定ack是管理自己还是我必须在代码中管理它。
哪种方法正确?
将每个basicAck发送多个设置为true
或
等到10个ack应该被发送出来并且只发送最后一个,AMQP将自动发送所有先前的队列。 (多次设置为true)
答案 0 :(得分:2)
TL; DR multiple = true在某些情况下更快,但需要更多仔细的簿记和批次要求
消费者获得具有特定于该消费者的单调增长ID的消息。 id是一个64位的数字(它实际上可能是一个无符号的32位,但由于Java没有那么长)称为传递标记。预取是消费者将收到的最多消息。
当您使用多个true
确认最高的投放标记时,它将确认所有未使用的邮件,其中包含较低的投放标记(较小的数字),而该投放标记是消费者尚未完成的。显然,如果你有高预取,这比每个消息的执行速度快。
现在,RabbitMQ知道消费者收到了消息(未经消费的消息),但它并不知道所有消息是否都被正确消费。因此,开发人员必须确保所有以前的消息都已被消耗。消费者将按顺序传递消息(我相信内部客户端使用BlockingQueue)但是根据下游使用的库/客户端,消息可能不是。
因此,当您将消息一起批处理(例如,事务处理或将一组消息发送到某个其他系统)或可靠地缓冲时,这实际上只能很好地工作。通常这是通过阻塞队列完成的,然后定期排空队列以将一组消息发送到下游系统。
另一方面,如果您实时传输每条消息,那么您无法做到这一点(即multiple = false)。
还有一个消息在群组中是不好的情况(例如从内部队列中排出......而不是兔子队列),你不会没那个坏的消息。如果是这种情况,您也不能使用多个= true
。
最后,如果你等待一定数量的消息(而不是说时间)超过预取,你将无限期地等待....不是一个好主意。您需要按时等待,并且消息数必须为<=
预取。
正如您所看到的,正确使用多个= true
。
答案 1 :(得分:1)
关于Prefetch value is the max number of messages that will get queued before reaching its limit.
的第一个更正 - 这不是预取值;预取值是消费者&#34;获得的UN-ACKed消息的数量。从队列中。因此,它们被分配给消费者,但在被确认之前一直保持在队列中。当预取为1时,从here引用
这告诉RabbitMQ不要给一个工人提供多条消息 时间。或者,换句话说,不要向工人发送新消息 直到它处理并确认了前一个。
对于你的问题:
我不确定ack是管理自己还是我必须管理 这在代码中。
您可以将auto ack标志设置为true,然后您可以说the ack's manage themselves