提问者:小点点

将RabbitMQ中的消息作为“循环”分发到运行在Heroku dynos上的消费者


我有一个RabbitMQ设置,其中作业被发送到交换,交换将它们传递到队列。使用者依次正确地执行队列中的作业。但是,这些作业都是长流程(至少几分钟)。对于可伸缩性,我需要能够让多个使用者从队列顶部选择一个作业并执行它。

使用者正在一个叫做“队列”的Heroku dyno上运行。当我缩放dyno时,它似乎为每个dyno创建了额外的消费者(我可以在RabbitMQ仪表板上看到这些)。但是,队列中的任务数量不变--额外的使用者似乎什么也不做。请看下图了解我的设置。

我是不是漏了什么?

  1. 为什么消费者表现为“闲置”?我从日志中了解到,至少有一个使用者正在积极地完成一个任务。
  2. 当至少有一个消费者确实在努力工作时,我的消费者利用率如何为0%。
  3. 如何使其他三个使用者实际从队列中拉出一些作业?

谢谢

编辑:我发现循环调度实际上是有效的,但只有当消息被发送到队列时附加的使用者已经在运行。在我看来这是违反直觉的行为。如果我看到一个很大的队列,并且想要添加更多的消费者,那么添加的消费者将什么都不做,直到更多的项目被添加到队列中。


共1个答案

匿名用户

从另一个答案中找出关键点,这里可能的罪魁祸首是预取,如“消费者确认和发布者确认”下所述。

服务器将向使用者发送批处理,而不是一次传递一个消息并等待它被确认。如果使用者确认了一些消息但随后崩溃,则剩余的消息将发送给另一个使用者;但如果使用者仍在运行,未确认的消息将不会发送给任何新的使用者。

这解释了你看到的行为:

  1. 您可以创建队列,并将一些消息传递给它,而不运行使用者。
  2. 您运行一个使用者,它预取队列上的所有消息。
  3. 您运行第二个消费者;尽管队列不是空的,但所有消息都标记为已发送到第一个使用者,等待确认;因此第二个使用者处于空闲状态。
  4. 新消息到达队列;它以循环方式分发给第二个消费者。

解决方案是在使用者中指定basic.qos选项。如果将此设置为1,RabbitMQ将不会向使用者发送消息,直到它确认了前面的消息;具有该设置的多个使用者将以严格的循环方式接收消息。