RabbitMQ-每个用户仅允许一个进程

时间:2019-11-04 22:25:03

标签: rabbitmq queue sharding

为简短起见,这是一种简化的情况:

我需要实现一个队列,以对导入的数据文件进行后台处理。我想为这个特定任务(例如10个)指定一些消费者,以便可以并行处理多个用户。同时,为了避免并发数据写入出现问题,我需要确保没有一个用户同时在多个使用者中得到处理,基本上单个用户的所有文件应按顺序进行处理。

当前解决方案(但感觉不正确):

  • 具有1个队列,所有发布任务都在该队列中发布(file_queue_main
  • 有10个队列用于文件处理(file_processing_n
  • 具有1个结果队列(file_results_queue
  • 具有一个管理器进程(在本例中为node.js),该进程逐个使用来自file_queue_main的消息,并决定将哪个消息分发到file_processing队列。基本上跟踪file_processing在哪个队列中正在处理当前用户。

以下是我当前解决方案和预期行为的一些动画: enter image description here

RabbitMQ甚至是完成这项工作的工具吗?由于某种原因,感觉就像某种反模式。感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

与我无关的部分是经理流程。它必须知道每个使用方的当前状态,并且还必须停止并等待所有处理器都在其他用户上工作。理想情况下,您希望让每个进​​程都忽略其他进程。从处理队列中获得的收益也很少,只有当处理器已经在处理来自同一用户的消息时才使用。

最终,最好的解决方案将完全取决于您的预期使用情况以及下一条消息来自已被处理的用户的可能性。如果您希望一次收到的大多数邮件都是10个或更少的用户,那么您所拥有的可能会很好。如果您希望只偶尔处理来自多个不同用户的消息,那么您的处理队列将在很多时间都是空的,并且会造成很多不必要的复杂性。

您可以在此处执行的其他操作:

  • 让所有使用者都从同一队列中拉出并使用某种分布式锁定来防止冲突。如果消费者从正在处理的用户那里收到一条消息,请重新排队并继续。

  • 设置队列路由,以便来自同一用户的消息将始终发送到同一使用者。不利之处在于,如果您没有将流量平均分配出去,则可能会备份一些消费者,而其他消费者则闲置。

此外,如果您一次从同一个用户那里收到大量必须按顺序处理的消息,我想问一下它们是否应该完全是单独的消息。为什么不发送一条包含要处理的事物列表的消息?事件队列的大部分好处来自能够将每个事件视为可以单独处理的离散项。

答案 1 :(得分:0)

如果用户具有唯一ID,或者正在处理的文件具有唯一ID,则对ID进行哈希处理以输入处理队列。这样,您将始终在同一处理队列中排队相同的用户/文件任务。

我不确定这将如何影响处理队列的队列长度。