我对rabbitmq具有以下配置
prefetchCount:1
ack-mode:自动。
我有一个交换,该交换附加了一个队列,该队列附加了一个使用者。根据我的理解,如果队列有多个消息,那么将发生以下步骤。
在通道上排队写数据。
由于ack模式是自动的,因此只要队列在通道上写入消息,消息就会从队列中删除。
消息传给消费者,消费者开始对该数据进行处理。
由于Queue已收到上一条消息的确认,因此Queue在Channel上写入了下一个数据。
现在,我的疑问是,假设使用者尚未完成之前的数据。下一个数据队列写入通道后会发生什么?
另外,假设prefetchCount为10,而我只有一次消费者附加到队列,这10条消息将驻留在哪里?
最佳答案
您描述的场景是RabbitMQ文档中提到的场景,在this blog post中进行了详细说明。具体来说,如果您设置了足够大的预取次数,并且发布率相对较低,那么RabbitMQ服务器将变成一个高级网络交换机。当确认模式设置为自动时,预取限制将被有效禁用,因为永远不会有未确认的消息。通过自动确认,消息一经传递即被确认。这与具有任意大的预取次数相同。
如果预取> 1,则消息将存储在客户端库的缓冲区中。确切的数据结构将取决于所使用的客户端库,但据我所知,所有实现都将消息存储在RAM中。此外,使用自动确认,您无法知道特定使用者何时实际阅读和处理消息。
因此,这里有一些要点:
预取限制与自动确认无关,因为从不存在任何未确认的消息,因此
使用消费者时,自动确认没有多大意义
关闭自动确认时或使用autoack = on时,足够大的预取将导致消息代理不进行任何排队,而仅进行路由。
现在,这里有一些专家意见。我发现消息代理程序的整个概念都“向后推”消息,这有些倒退,因此,正因为如此-正确配置它很困难,而且尚不清楚这样做的好处。队列系统很自然地适合于基于拉的系统。处理完当前消息后,处理器可以向代理请求下一条消息。这种方法将确保负载自然平衡,并且在处理器断开连接或被淘汰时消息不会丢失。
因此,我的建议是完全放弃使用消费者,而改用basic.get
。