与RabbitMq共享一个工人池

时间:2016-09-27 07:36:35

标签: rabbitmq message-queue priority-queue task-queue

我正在构建一个多租户应用程序,用户可以提交要由工作人员处理的批量任务(工作人员数量是动态的)我想要实现的目标如下:

  • 如果我们有一个用户的单个批次,让所有工作人员处理来自此单个用户的消息
  • 如果另一个用户提交批处理作业,则每个用户获得一半的工作人员(这样第一个用户现在工作速度较慢,而后一个用户不必等到第一个用户完成他所有冗长的工作)

工作队列是否可能? (出于某种原因,这感觉就像FIFO和队列的想法一样,但不管怎样,这是我的用法:D)

1 个答案:

答案 0 :(得分:1)

您可以查看优先级队列实施:https://www.rabbitmq.com/priority.html

如果这对您不起作用,您可以尝试其他一些黑客来实现您的目标:

您可以将100个队列绑定到主题交换,并将路由键设置为用户ID%100的哈希值,即每个任务的密钥在1到100之间,同一个用户的任务将具有相同的密钥。每个队列都绑定一个介于1和100之间的唯一模式。现在,您有一组工作人员以随机队列号开头,然后在每个作业之后递增该队列号,再次%100以在队列100之后循环回队列1。

现在,您的工作人员队伍可以并行处理多达100个唯一身份用户,或者如果没有其他工作要做,所有工作人员都可以专注于单个用户。如果工作人员需要在每个作业之间循环遍历所有100个队列,那么在单个用户在单个队列中只有大量作业的情况下,您自然会在每个作业之间产生一些开销。较少数量的队列是解决此问题的一种方法。您还可以让每个工作者保持与每个队列的连接,并从每个队列中消耗最多一条未确认的消息。然后,只要未确认的消息超时设置得足够高,工作人员就可以更快地循环遍历内存中的待处理消息。

或者,您可以创建两个交换,每个交换都有一个绑定队列。所有工作都进入第一个交换和队列,一组工人消耗。如果工作单元花费的时间太长,工作人员可以取消它并将其推送到第二个队列。当第一个队列中没有任何内容时,工作程序仅处理第二个队列。您可能还需要一些具有相反队列优先级的工作人员,以确保在短期任务到来的永不结束的流程中仍然处理长时间运行的任务,以便最终始终处理用户批处理。这不会真正将您的工作人员分配到所有任务中,但它会阻止一个用户阻止您的工作人员为同一个用户或另一个用户执行短期运行任务。它还假设您可以取消作业并在以后重新运行它而不会出现任何问题。这也意味着将会从超时的任务中浪费资源,并且需要以低优先级重新运行。除非您可以提前识别快速和慢速任务

如果单个用户有100个慢速任务,那么100个队列的第一个建议也会出现问题,然后另一个用户发布一批任务。在完成其中一项缓慢任务之前,这些任务不会被查看。如果这是一个合法的问题,你可能会将两种解决方案结合起来。