RabbitMQ 3.2.0 中的联合队列
我们在 RabbitMQ 3.2.0 中添加了对联合队列的支持。这篇博文解释了它们的作用以及如何使用它们。
(顺便说一句,如果这看起来像一堵文字墙,我表示歉意,我的绘画技巧不佳。RabbitMQ 团队中更有艺术天赋的成员正在绘制一些漂亮的图表……)
它们的作用是什么?
队列联合背后的理念是在不同代理上的队列之间进行负载均衡消息。如果您有一组相互联合的队列,则生产者可以发布到这些队列,而消费者可以从这些队列消费,而无需(过多)考虑位置。
因此,联合交换机真正由发布-订阅场景驱动(所有地方的消费者都能够看到任何地方发布的消息),而联合队列则适用于工作队列场景(某个地方的消费者能够看到任何地方发布的消息)。发布者可以在任何地方发布,联合机制会自动将消息移动到可以消费它们的地方,但一条消息在任何给定时间只能在一个地方。
顺便说一句,这与人们通常谈论负载均衡的方式不同。通常,我们认为负载均衡是在“事前”进行的——想象一下,发布者随机选择多个队列中的一个进行发布,每个队列都有一些本地消费者。这种方法的问题在于,如果一个队列的消费者落后或完全停止工作,则没有办法进行平滑处理。队列联合在“事后”进行负载均衡,将消息移动到可以处理它们的地方。
自 3.1.x 以来,联合链接的性能有所提高(在 无确认模式 下速度大约快了两倍,在确认模式下速度快了 50%)。但我们仍然希望避免在可以避免的情况下移动消息,因此队列联合仅在 B 有消费者但没有消息,并且 A 的消息多于其消费者可以(立即)处理的消息时,才将消息从队列 A 移动到队列 B。队列联合的理想用户将在每个单独的队列中平衡发布和消费,从而使联合无事可做。😃至少在某个消费者落后之前……
它们不适用于什么?
现在交换机和队列都可以联合,人们很容易想到“好吧,我可以联合所有内容,然后我将拥有一个大型虚拟代理,就像集群一样,但具有分区容错能力”。当然,正如我们老朋友 CAP 定理所暗示的那样,事情并非如此简单;如果您获得了(P)分区容错能力,则必须失去其他一些东西,在联合的情况下,那就是(C)一致性。联合队列永远只会将给定消息存储在一个位置;没有镜像。将其视为 RAID-0 而不是 HA 的 RAID-1。
当然,如果您想要 RAID-10,您可以将集群与联合连接起来……
那么如何联合一个队列呢?
这很简单!定义一个或多个上游,就像联合交换机一样,然后定义一个匹配您的队列的策略,并定义一个 federation-upstream-set
或 federation-upstream
,这与联合交换机一样。请参阅 文档 以获取更多详细信息,但实际上它的工作方式与联合交换机相同。