跳至主要内容

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 绑定队列将始终接受消息,但随着时间的推移,它们将倾向于变得更小,而不是更大。呼!

© 2024 RabbitMQ. All rights reserved.