1

我正在使用 RabbitMQ 处理应用程序日志(安装 Windows Server 2008)。应用程序向交易所发送消息。我有一个专用队列,可以将消息转发给它。然后,我有一个 Windows 服务连接到该队列,将消息拉出,并将它们持久保存到 DB。我有 n 个客户端实时连接到交换机以锁定流,因此一次有 n 个连接。其中一些客户端可能不会在代码中关闭()它们的连接。许多客户端具有长时间运行的连接。

当消息从队列中拉出时,它们会自动确认,因此队列中没有任何未确认的消息。然而,我看到兔子的记忆随着时间的推移而增长。它在第一次打开时从 32K 左右开始,然后慢慢上升,直到超过阈值并阻止传入连接。

我有 .NET 和 Java 客户端——但都是自动确认的。

阅读文档时,我没有看到任何关于 Rabbit 如何使用内存的描述——即我不明白为什么内存会随着时间的推移而膨胀。消息被删除和确认,在我看来这意味着 Rabbit 将不再持有它,因此可以释放相关的内存,从而导致稳定的内存使用配置文件。

我看不出在 Rabbit 中摆弄记忆拨盘会有什么帮助——使用率会随着时间的推移而上升:最终我会超过它。

我的猜测是,我的客户做错了什么导致内存随着时间的推移而增长,但我想不出为什么会这样。

 why does Rabbit memory usage creep up when no messages are kept on any queues? 

 what coding practices could cause the RabbitMQ server to 
 retain (and grow) memory?
4

1 回答 1

1

您是否有可能将其他队列绑定到交易所?检查交换下的 Rabbit 管理页面,单击您的交换,并检查绑定到它的队列。可能是您的一个客户在声明交换时无意中将未命名(系统随机命名)队列绑定到交换,并且消息在那里堆积。

要检查的另一件事是 QoS 设置 - 如果您将 QoS 设置为默认值(无限),那么 Rabbit 将立即向任何客户端发送消息,无论它们已经持有多少消息。这会导致大量的记账,比如哪个客户端在服务器上有哪个消息,以及客户端上有一个大缓冲区。

确保将您的 QoS 预取限制设置为更合理的值,例如 100。这样,如果您有 1M 条消息并且只有 1 个客户端预取为 100,Rabbit 将只向客户端发送 100 条消息并保留其他 999900在服务器上的磁盘上,并且不会使用几乎一样多的内存。

这是我的应用程序内存膨胀的一个重要原因,现在我已经解决了预取问题,一切都很好。

于 2013-01-17T19:23:52.187 回答