RabbitMQ - 按优先级使用多个队列

eld*_*d87 6 priority-queue amqp rabbitmq consumer producer

我需要升级我们的生产者/消费者基础设施。

当前设置如下所示:

  • 一组具有不同优先级(低、中、高)的 3 个队列。
  • 当我们的客户生成任务(即处理图像)时:
    • Producer 将消息添加到相关队列中。
    • 其中一名工人解决了这个问题。

这种方法的问题在于,如果客户生成大量任务,它可能会占用队列中的所有可用插槽,这可能会导致该队列中的服务拒绝(或巨大延迟)。

建议更改:

  • 每个客户(或一组)都应该有专门的Consumer(或一组)。
  • 当消费者空闲时,他们应该处理其他客户的消息。

例如,我们有一组消息:

 1. Producer: Customer1, Queue: High, Payload: {}, Created: Today 16:00:00
 2. Producer: Customer2, Queue: High, Payload: {}, Created: Today 16:00:01
 3. Producer: Customer1, Queue: High, Payload: {}, Created: Today 16:00:02
 4. Producer: Customer1, Queue: High, Payload: {}, Created: Today 16:00:03
Run Code Online (Sandbox Code Playgroud)

我们有以下消费者:

1. Consumer1: Dedicated for Customer1
2. Consumer2: Dedicated for Customer1
3. Consumer3: Dedicated for Customer2
Run Code Online (Sandbox Code Playgroud)

预期结果:

1. Consumer1 will address Message#1
2. Consumer2 will address Message#2
3. Consumer3 will address Message#3
4. Message#4 Any of the Consumers can address it, since Consumer1/3 are dedicated to the given Producer and Consumer2 will be idle.
Run Code Online (Sandbox Code Playgroud)

总而言之,客户应该始终尽快获得专用数量的消费者(或更多可用时),每当无事可做时,他的消费者可以消费其他客户的其他消息。

我试图找出实现该目标的最佳方法是什么,即使以从 RabbitMQ 切换到任何其他消息传递代理为代价。

到目前为止,我发现(使用 RabbitMQ)的唯一方法是使用联邦队列并形成一个完整的双向图(每个队列都是所有其他队列的上游,反之亦然)。

ist*_*iuk 1

没有任何公式可以为每种类型的工作负载产生公平的排队;处理任务的数量、统一程度和时间很重要。也就是说,我怀疑联合队列对于公平性有任何帮助。

您可以使用优先级队列消费者优先级。结合低prefetch计数,就有可能获得适合客户期望的调度。

然而,这些机制都不会根据客户的使用容量来限制他们;如果客户在短时间内发送了太多高优先级的慢处理任务,它仍然会阻塞您的其他客户。

既然您建议每个客户一个消费者是可能的,我知道客户数量不是很大。一个需要考虑的解决方案是为每个客户设置优先队列。来自所有这些队列的消息可以由多个工作线程使用的缓冲队列以循环方式选取,如下图所示,来自SE 上的相关问题:

排队

这样,任何客户都不会获得优势,并且您在某种程度上将公平的含义(在您的上下文中)与实际的负载平衡脱钩。

我自己没有尝试过,但我认为shovel 插件足以实现重新排队(图中的橙色)。如果您想要更详细的信息,例如配额决定什么是公平的,什么是不公平的,那么实施您自己的重新排队服务可能是值得的。