RabbitMQ跨多个队列的多个使用者-消息被延迟处理

时间:2019-05-30 14:31:54

标签: multithreading rabbitmq messaging

我们最近在使用RabbitMQ的应用程序中遇到了意外的行为。 RabbitMQ版本是3.6.12,我们正在使用.NET Client 5.0.1

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

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

请注意,我们注意到,当应用程序仅订阅一个队列时,不会发生此问题,而当涉及多个队列时,它将成为一个问题。

最好使用以下示例进行说明:

  • 我们有一个简单的消耗性应用程序,可以订阅两个队列, 一种用于命令,另一种用于事件。该应用程序有7 消费者,每个消费者都有自己的渠道和EventingBasicConsumer我们 启动一个简单的发布应用程序,该应用程序发布20条消息, 相隔第二。每个消息都是一个事件,因此会发布到该事件 除了第5条和第10条消息(它们是命令和 发送到命令队列。请注意,处理每个事件都不会 延迟,而命令则需要30秒

  • 下表描述了与在多个队列中为消息分配多个通道有关的观察结果:

enter image description here

  • 一旦Message5在使用C1的30秒后完成,则立即将Messaqe9分配给C1并立即进行处理 一旦Message10在使用C2的30秒后完成,则立即将Messaqe11分配给C2并立即进行处理

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

是否有可能当多个使用者订阅多个队列时,即使有一些使用者当前处于空闲状态,RabbitMQ仍可以分配一条消息供忙碌的使用者处理?

是否有任何文档说明RabbitMQ算法,该算法选择从一系列消费者中触发哪些EventingBasicConsumer.received消费者?

1 个答案:

答案 0 :(得分:1)

我们已解决此问题。

在RMQ文档(view composer)中,我们遇到了以下问题: “每个渠道都有其自己的调度线程。对于最常见的用例,每个通道一个消费者,这意味着消费者不会占用其他消费者。如果每个通道有多个消费者,请注意长期运行的消费者可能会阻止调度该频道上其他消费者的回调。”

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