解决RabbitMQ无故占用大量内存的问题
2024年注:这篇博文实际上是一个反例。查问题不应该像这样查个似是而非就认为大功告成了。印象里这篇文章发出后不久,RMQ 又 OOM 了。
按今天的眼光来看,这篇文章至少有这些槽点:
- 为什么 Redis 的带宽使用高企?替换 RMQ 从理论上能解决 Redis 作为 Broker 时带宽高的问题吗?
- 有证据能证明是 Socket Buffer 导致的内存使用量过高吗?
- 线上冒烟测试
还好当年做掌上武大的时候对崩溃的宽容度比较高,不然有够被喷的。把这篇文章放在这里谨以纪念在自强Studio的时光,文章的内容就别参考了。
刚刚接手自强Studio的后台开发,碰到了Redis做Celery的broker时大量占用Redis服务器宽带资源的问题。面对有限的经费,我决定把和Celery搭档的做Broker的Redis更换为RabbitMQ。
刚切换到RabbitMQ以后,流量是有显著下降,但是却发现了一个奇怪的问题:服务器内存资源占用总是从50%在两三天的时间内飙升至80%,之后服务器内存调度缓慢,几乎处于宕机的状态。
起先怀疑是服务器配置不足(服务器只有1G内存),然而在咨询了@liby、@iceboy和@twd2等大神以后,得知RabbitMQ在1G的内存下跑完全可行。
在百度和必应上搜索无果。搜到的大多是关于vm_memory_high_watermark的内容。修改后无效。之后细致的分析了RabbitMQ的内存,发现高涨的是binary部分。遂修改关键词,重新选择合适的搜索引擎,搜到了这篇文章。
解决方法就是,在RabbitMQ配置文件 rabbitmq.config中修改 tcp_listen_options中有关Socket Buffer的配置。该问题提供的参数如下:
[{rabbit, [{tcp_listen_options, [binary,
{sndbuf, 1024},
{recbuf, 1024},
{buffer, 1024},
{packet, raw},
{reuseaddr, true},
{backlog, 128},
{nodelay, true},
{linger, {true, 0}},
{exit_on_close, false}]}]}].
未强制指定时,系统会自动指定Buffer的大小(想想一堆数据全部丢进去,着实可怕)。具体的体现就是Binary内存使用高涨。RabbitMQ的文档里没有详尽介绍这个参数,然而这个参数尽然会带来这么大的内存使用差!
修改此参数后,RabbitMQ已正常运行一个多星期。
- 原文作者:ShadowMov's Blog
- 原文链接:https://shadowmov.com/posts/solve-rabbitmq-oom/
- 版权声明:本作品采用CC BY-SA 4.0. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。