RabbitMQ 跨多个队列的多个消费者 - 消息延迟处理

Posted

技术标签:

【中文标题】RabbitMQ 跨多个队列的多个消费者 - 消息延迟处理【英文标题】:RabbitMQ multiple consumers across multiple queues - messages delayed from being processed 【发布时间】:2019-10-16 05:31:52 【问题描述】:

我们最近在使用由 RabbitMQ 提供支持的应用程序时遇到了意外行为。 RabbitMQ 版本是 3.6.12,我们使用的是 .NET Client 5.0.1

应用程序订阅两个队列,一个用于命令,另一个用于事件 - 我们也使用手动确认。 我们的应用程序配置为有 7 个消费者。每个都有自己的频道(IModel),每个都有自己的 EventingBasicConsumer 当 EventingBasicConsumer.Received 被触发时,我们最终会处理消息。

我们的应用程序必须尽可能在消息被路由到队列时处理消息,并且迄今为止我们没有遇到任何问题。 但是最近,我们发现,当我们处理的一条消息需要很长时间才能完成时,尽管有许多可用的消费者 (6) 不忙,但它会延迟处理另一条消息。

请注意,我们观察到,当应用程序仅订阅单个队列时不会发生此问题,当涉及多个队列时会出现问题。

最好用下面的例子来说明:

我们有一个简单的消费应用程序,它订阅了两个队列, 一种用于命令,一种用于事件。此应用程序有 7 消费者,每个人都有自己的频道和 EventingBasicConsumer 我们 启动一个简单的发布应用程序,发布 20 条消息,一个 第二分开。每条消息都是一个事件,因此会发布到事件中 除了第 5 条和第 10 条消息之外的队列,它们是命令和 发送到命令队列。请注意,每个事件的处理都没有 延迟,而命令需要 30 秒

下表描述了我们观察到的关于为多个队列中的消息分配多个通道的情况:

一旦 Message5 在 30 秒后与 C1 一起完成,则 Messaqe9 立即分配给 C1 并立即处理 一旦 Message10 在 C2 30 秒后完成,然后 Messaqe11 立即分配给 C2 并立即处理

因此,在我们看来,通道的分配似乎是每个队列独立完成的 - 这意味着如果某些消息需要很长时间来处理,您可能会延迟执行。

是否有可能当多个消费者同时订阅多个队列时,即使有空闲的消费者,RabbitMQ 也可以分配一条消息让一个忙碌的消费者处理?

是否有任何文档解释了从消费者集合中选择哪些消费者 EventingBasicConsumer.received 触发的 RabbitMQ 算法?

【问题讨论】:

【参考方案1】:

我们已经解决了这个问题。

在 RMQ 文档 (https://www.rabbitmq.com/api-guide.html#consuming) 中,我们遇到了以下内容: “每个 Channel 都有自己的调度线程。对于每个 Channel 一个消费者的最常见用例,这意味着消费者不会阻止其他消费者。如果每个 Channel 有多个消费者,请注意长时间运行的消费者可能会阻止调度对该频道上其他消费者的回调。”

在我们的代码中,每个渠道有 2 个消费者,这意味着消费者可以容纳其他消费者。 我们更改为每个频道有一个消费者,这解决了问题。

【讨论】:

我们遇到了与此处描述的问题类似的问题。更改为每个队列一个消费者允许继续处理队列上的消息。谢谢bstack!

以上是关于RabbitMQ 跨多个队列的多个消费者 - 消息延迟处理的主要内容,如果未能解决你的问题,请参考以下文章

RabbitMQ中有大批量的消息,此时多个消费者同时访问消息队列是怎样取里面的消息的?

rabbitMQ 点对点 一个队列可以多个消费者吗?

rabbitmq 生产者 消费者(多个线程消费同一个队列里面的任务。)

跨多个队列的 ActiveMQ 消息组消费者选择?

RabbitMQ发布订阅模式

RabbitMQ怎样能实现多个队列由一个消费者来接收消息