当RabbitMQ中有其他使用者时,消息会堆积在使用者上-使用兔子作为导轨

时间:2019-07-30 23:03:07

标签: ruby rabbitmq bunny

RabbitMQ中的队列消息正在堆积并在单个使用者上等待,而其他使用者可用。

我们使用RabbitMQ作为我们的信使服务。我们使用兔子来创建连接并设置带有传递消息的队列。

在使用兔子进行的Rails设置中,我们遇到一个问题,我们有一个队列,其中有8个消费者在该队列上侦听消息。消息进入时,理想情况下,它们应该是循环使用消费者的:例如,队列中有4条消息,消费者1接听消息1,-消费者1忙,消费者2接听消息2,消费者2忙,消费者3收到消息3,依此类推。

无论如何,我们遇到的问题是,队列中有4条消息,消费者1收到消息1,消费者1忙,消费者2-8可用,但是消息2-4堆积在队列中,等待消费者1到变得可用并处理消息。

我觉得我已经做了很多研究,只是无法完全弄清楚如何阻止消息堆积并等待单个消费者。

有没有人对此有经验,或者对如何解决此问题有任何想法?

conn = Bunny.new(bunny[0])
conn.start
ch = conn.create_channel
q = ch.queue("#{record_queue_name}", :durable => true)
q.subscribe(:manual_ack => true, :arguments => {"x-priority" => 10}, :block => true) do |delivery_info, properties, payload|
ch.acknowledge(delivery_info.delivery_tag, false)

我们希望每当有消息发送到RabbitMQ时,消费者都以先到先得的方式接收消息,而不是在其他消息可用时将多个消息堆叠起来等待繁忙的消费者。

编辑: 繁殖方法: 同时启动3个消费者。 推送6条消息-使用者1-3现在忙于队列中的3条消息。 重新启动2和3,当2和3再次监听时,仍有3条消息在队列中等待消费者1。消费者2和3仍然可用。

重新启动使用者1,现在3个排队的消息首先到达第一台服务器,重新启动到使用者2和3。

无论使用者是否重新启动,我都需要消息先到达第一台服务器。

1 个答案:

答案 0 :(得分:1)

RabbitMQ正在按预期工作。

由于您的代码未设置QoS / prefetch,因此RabbitMQ向您的第一个使用者发送所有六个消息。由于该使用者花费时间来确认消息(通过代码中的45秒睡眠来模拟),因此这六个人保持“未确认”状态,而其他两个使用者则没有任何工作。重新启动其他两个使用者没有任何作用,因为所有六个消息都处于“未确认”状态,等待第一个使用者的确认。

当您重新启动第一个使用者时,RabbitMQ检测到丢失的连接,并使这六个消息排队进入“就绪”状态,并将所有六个(最有可能的)消息传递给另一个使用者,然后问题再次发生。

有关如何设置预取的信息,请参见this runnable code sample。在1的预取下,RabbitMQ最多将一条消息传递给使用者,并在等待确认之前将另一条消息传递给该使用者。这样,邮件将在您的使用者之间分发。


注意: RabbitMQ团队监视rabbitmq-users mailing list,并且有时仅在StackOverflow上回答问题。