RabbitMQ使用者过载

RabbitMQ使用者过载,rabbitmq,amqp,producer-consumer,rabbitmq-exchange,Rabbitmq,Amqp,Producer Consumer,Rabbitmq Exchange,我一直在读AMQP的原则。(). 这篇文章很有帮助,写得也很好,但是关于消费者知识的一个特别的地方真的很让人困惑,下面是引语: 使用自动确认模式时要考虑的另一件事是用户超载> < /P> 消费者超载?消息队列由代理处理并保存在RAM中(如果我理解正确的话)。这是关于什么的?消费者是否有第二个队列? 那篇文章的另一部分更令人困惑: 因此,用户可能会被交付速度所压倒,可能会在内存中积累一个积压工作并耗尽堆或让操作系统终止其进程 什么积压?这一切是如何协同工作的?消费者完成了哪部分工作(当然除了消费和

我一直在读AMQP的原则。(). 这篇文章很有帮助,写得也很好,但是关于消费者知识的一个特别的地方真的很让人困惑,下面是引语:

使用自动确认模式时要考虑的另一件事是<强>用户超载> < /P> 消费者超载?消息队列由代理处理并保存在RAM中(如果我理解正确的话)。这是关于什么的?消费者是否有第二个队列? 那篇文章的另一部分更令人困惑:

因此,用户可能会被交付速度所压倒,可能会在内存中积累一个积压工作并耗尽堆或让操作系统终止其进程


什么积压?这一切是如何协同工作的?消费者完成了哪部分工作(当然除了消费和处理消息之外)?我原以为代理保持队列活动并转发消息,但现在我正在阅读一些神秘的积压和消费者过载。这真是令人困惑,有人能解释一下吗,或者至少给我指出好的来源吗?

能够发出背压信号是分布式系统中的一个基本问题。如果没有明确的确认,消费者就无法对经纪人说“慢下来”。启用自动确认后,代理一旦收到TCP确认,就会从其内存/磁盘中删除消息


但是,这并不意味着消费应用程序已经处理了消息,或者有足够的内存来存储传入的消息。本文中的backlog只是一个数据结构,用于存储未处理的消息(在消费者应用程序中)

我相信您所指的文档处理的是,在我看来,AMQP 0-9-1或RabbitMQ实现中的某种设计缺陷

考虑以下场景:

  • 队列中有数千条消息
  • 单个使用者使用
    AutoAck=true
    订阅队列,并且未设置预取计数
会发生什么?

RabbitMQ的实现是向没有预取计数的客户机传递任意数量的消息。此外,对于自动确认,预取计数是不相关的,因为消息在传递给消费者时被确认

内存缓冲区: 消费者的默认客户端API实现有一个内存缓冲区(在.NET中,它是某种类型的阻塞集合(如果我没记错的话)。因此,在处理消息之前,但在从代理接收消息之后,它会进入此内存保留区。现在,设计缺陷就是此保留区。消费者别无选择,只能接受来自代理的消息,因为它是异步发布到客户端的。这是与的一个缺陷(请参阅第53页)

因此,此时队列中的每一条消息都将立即传递给消费者,消费者将被消息淹没。假设每条消息很小,但需要5分钟处理,则完全有可能这一消费者能够在其他消费者连接到它之前耗尽整个队列。并且ce
AutoAck
打开时,代理将在交付后立即忘记这些消息

显然,如果您希望处理这些消息,这不是一个好的场景,因为它们已经离开了代理的相对安全性,现在位于消费端点的RAM中。假设遇到了一个异常,导致消费端点崩溃-poof,所有消息都消失了

如何解决这个问题?


您必须关闭自动确认,通常设置合理的预取计数也是一个好主意(通常2-3就足够了).

谢谢您如此详细的回答!现在有了更多的意义!如果我在没有指定预取计数的情况下关闭自动确认,会发生什么?消费者还会收到大量的消息吗?或者我不太理解预取计数在这里的作用?我必须去查看,但实际上,我认为是这样。预取计数超过1只有在非常有限的情况下才有意义,在这种情况下,消息处理所需的时间与消息传递所需的时间大致相同(没有太多这样的用例)。我不喜欢预取。也许本文有帮助: