跳到主要内容

RabbitMQ 3.3 中的消费者偏向

·3 分钟阅读
Simon MacMullen

在开始之前我先提醒您:这是另一篇关于 RabbitMQ 3.3 中与性能相关的更改的冗长博客文章。仍然关注吗?很好。

所以在之前的文章中,我提到了“一个新功能,我将在以后的博客文章中讨论”。该功能是消费者偏向。

RabbitMQ 中的每个队列都是一个 Erlang 进程,并且像所有 Erlang 进程一样,它响应发送给它的消息。这些消息可能代表发布到队列的 AMQP 消息,或者传入的 basic.get 请求,或者告知队列消费者的网络连接现在不再繁忙,因此它可以再次接收消息等等。一切都是消息。

当队列不繁忙时,它只是响应传入的消息。但是随着消息速率的上升,并且队列开始更加努力地工作,我们进入了一种状态,即队列正在使用所有可用于它的 CPU 周期。此时,入站消息开始排队等待队列处理!流量控制阻止它们无限期地积累 - 但它们正在积累这一事实可能会对队列产生一些后果。

一些入站消息有助于队列缩小(“此消费者可以再次接收消息”,“我想执行 basic.get”),而另一些则使队列增长(“我想发布新消息”)。因此,当队列全速运行时,我们希望优先处理有助于队列缩小的消息,以便队列趋于保持为空而不是永远增长。

我们在 RabbitMQ 1.7.0 中添加了这样的偏向。

那我为什么要现在谈论它呢?那已经是五年前的事了!

不幸的是,事实证明,仅仅无条件地优先清空队列可能会产生不良的副作用 - 在某些情况下,队列可能会花费 100% 的时间向消费者传递消息,实际上我们确实收到了一些用户的报告,他们看到了完全相同的情况 - 所有消费者都将离线,队列将累积到非常大的大小,然后消费者将返回,队列将拒绝接受任何发布,直到它完全为空。这不是一个非常有用的队列。

因此,我们在 RabbitMQ 2.8.3 中去除了这种偏向,并回到了 CPU 密集型队列可能无限期增长的情况。

但我们仍然希望做得更好。在 3.3.0 中,我们终于能够做到了。

现在,队列不再无条件地优先缩小,而是能够持续监控其大小的变化率,并且在繁忙时,它们将优先处理有助于它们缩小的消息 - 但仅在它们传递的消息比接受的消息多 10% 之前。因此,CPU 密集型队列仍然会始终接受消息,但随着时间的推移,它们会倾向于变小而不是变大。 唷!

© . All rights reserved.