作为 'round robin' 在 Heroku dynos 上将消息从 RabbitMQ 分发给消费者 运行
Distribute messages from RabbitMQ to consumers running on Heroku dynos as a 'round robin'
我有一个 RabbitMQ 设置,其中作业被发送到交换器,交换器将它们传递到队列。消费者依次正确地执行队列中的作业。但是,这些作业是很长的过程(至少几分钟)。对于可伸缩性,我需要能够让多个消费者从队列顶部选择一个作业并执行它。
消费者在名为 'queue' 的 Heroku dyno 上 运行。当我缩放 dyno 时,它似乎为每个 dyno 创建了额外的消费者(我可以在 RabbitMQ 仪表板上看到这些)。然而,队列中的任务数量没有改变——额外的消费者似乎什么都不做。请查看下图以了解我的设置。
我是不是漏掉了什么?
- 为什么消费者显示为 'idle'?我从我的日志中知道至少有一个消费者正在积极地完成一项任务。
- 当至少有一个消费者肯定在努力工作时,我的消费者利用率怎么会是0%。
- 如何让其他三个消费者真正从队列中拉取一些工作?
谢谢
编辑: 我发现循环调度确实有效,但前提是当消息发送到队列。这对我来说似乎是违反直觉的行为。如果我看到一个很大的队列并且想添加更多的消费者,添加的消费者将不会做任何事情,直到更多的项目被添加到队列中。
我对Heroku不熟悉,所以我不知道Heroku worker是如何构建rabbitMQ消费者的,我只是快速浏览了下Heroku文档。
Why are the consumers showing as 'idle'?
我想你的意思是队列是 'idle'?因为队列的state
是关于队列的流量,它只是意味着队列的作业线程没有在做的作业。当队列中有消息发布时,它将变为'running'。
How can my consumer utilisation be 0% when at least one consumer is definitely working hard.
同queue state,官方解释,consumer utilisation
太低表示:
- 有更多消费者
- 消费者速度更快
- 消费者有更高的预取计数
在你的情况下,prefetch_count = 0
意味着预取没有限制,所以它太大了。而 Messages.total = Messages.unacked = 78
表示你的消费者太慢了,有两条消息已经被消费者处理了。
所以如果你的消息速率不够大,队列的state
和consumer utilisation
字段是没有用的。
If I saw a large queue and wanted to add more consumers, the added consumers would do nothing until more items are added to the queue.
因为这些未确认消息已经被现有消费者预取,除非您requeue
未确认消息,否则新消费者不会使用它们。
要从其他答案中找出关键点,这里可能的罪魁祸首是 预取,如 "Consumer Acknowledgements and Publisher Confirms" 所述。
服务器将批量发送给消费者,而不是一次传递一条消息并等待它被确认。如果消费者确认了一些但随后崩溃,则剩余的消息将发送给不同的消费者;但如果消费者仍然 运行ning,则未确认的消息将不会发送给任何新消费者。
这解释了您所看到的行为:
- 您创建队列,并向其传送一些消息,没有消费者 运行ning。
- 你 运行 一个消费者,它预取 队列中的所有消息。
- 你运行第二个消费者;尽管队列不为空,但所有消息都被标记为已发送给第一个消费者,等待确认;所以第二个消费者闲置。
- 一条新消息到达队列;它以循环方式分发给第二个消费者。
解决办法是specify the basic.qos
option在消费端。如果将其设置为 1,则 RabbitMQ 在确认前一条消息之前不会向消费者发送消息;具有该设置的多个消费者将以严格的循环方式接收消息。
我有一个 RabbitMQ 设置,其中作业被发送到交换器,交换器将它们传递到队列。消费者依次正确地执行队列中的作业。但是,这些作业是很长的过程(至少几分钟)。对于可伸缩性,我需要能够让多个消费者从队列顶部选择一个作业并执行它。
消费者在名为 'queue' 的 Heroku dyno 上 运行。当我缩放 dyno 时,它似乎为每个 dyno 创建了额外的消费者(我可以在 RabbitMQ 仪表板上看到这些)。然而,队列中的任务数量没有改变——额外的消费者似乎什么都不做。请查看下图以了解我的设置。
我是不是漏掉了什么?
- 为什么消费者显示为 'idle'?我从我的日志中知道至少有一个消费者正在积极地完成一项任务。
- 当至少有一个消费者肯定在努力工作时,我的消费者利用率怎么会是0%。
- 如何让其他三个消费者真正从队列中拉取一些工作?
谢谢
编辑: 我发现循环调度确实有效,但前提是当消息发送到队列。这对我来说似乎是违反直觉的行为。如果我看到一个很大的队列并且想添加更多的消费者,添加的消费者将不会做任何事情,直到更多的项目被添加到队列中。
我对Heroku不熟悉,所以我不知道Heroku worker是如何构建rabbitMQ消费者的,我只是快速浏览了下Heroku文档。
Why are the consumers showing as 'idle'?
我想你的意思是队列是 'idle'?因为队列的state
是关于队列的流量,它只是意味着队列的作业线程没有在做的作业。当队列中有消息发布时,它将变为'running'。
How can my consumer utilisation be 0% when at least one consumer is definitely working hard.
同queue state,官方解释,consumer utilisation
太低表示:
- 有更多消费者
- 消费者速度更快
- 消费者有更高的预取计数
在你的情况下,prefetch_count = 0
意味着预取没有限制,所以它太大了。而 Messages.total = Messages.unacked = 78
表示你的消费者太慢了,有两条消息已经被消费者处理了。
所以如果你的消息速率不够大,队列的state
和consumer utilisation
字段是没有用的。
If I saw a large queue and wanted to add more consumers, the added consumers would do nothing until more items are added to the queue.
因为这些未确认消息已经被现有消费者预取,除非您requeue
未确认消息,否则新消费者不会使用它们。
要从其他答案中找出关键点,这里可能的罪魁祸首是 预取,如 "Consumer Acknowledgements and Publisher Confirms" 所述。
服务器将批量发送给消费者,而不是一次传递一条消息并等待它被确认。如果消费者确认了一些但随后崩溃,则剩余的消息将发送给不同的消费者;但如果消费者仍然 运行ning,则未确认的消息将不会发送给任何新消费者。
这解释了您所看到的行为:
- 您创建队列,并向其传送一些消息,没有消费者 运行ning。
- 你 运行 一个消费者,它预取 队列中的所有消息。
- 你运行第二个消费者;尽管队列不为空,但所有消息都被标记为已发送给第一个消费者,等待确认;所以第二个消费者闲置。
- 一条新消息到达队列;它以循环方式分发给第二个消费者。
解决办法是specify the basic.qos
option在消费端。如果将其设置为 1,则 RabbitMQ 在确认前一条消息之前不会向消费者发送消息;具有该设置的多个消费者将以严格的循环方式接收消息。