解决RabbitMQ队列超长QueueingConsumer导致JVM内存溢出的问题
来源:互联网 发布:含氟牙膏推荐 知乎 编辑:程序博客网 时间:2024/06/05 17:13
我们的服务器使用RabbitMQ作为消息中转的容器。某天我怀疑RabbitMQ队列是否都能及时消化。于是用命令查询了下:rabbitmqctllist_vhosts | grep -P ".*\.host" | xargs -i rabbitmqctl list_queues-p {} | grep "queue"。 不查不知道,一查吓一跳:大多数服务器的队列基本上都是空的,但是有些服务器的某个队列竟然有超过500W条的记录。一般RabbitMQ进程占用内存不过100M-200M,这些队列超长的RabbitMQ进程可以占用超过2G的内存。
显然消息队列的消费者出现了问题。开发查看日志发现作为该队列消费者的Java服务的日志也卡住了,重启服务后(这点做得不对,应该用jstat、jstack进行排查,而不是直接重启)又很快卡住。这时候他才想起来用jstat,通过jstat发现JVM内存都耗尽了,之后进入无尽的FullGC,所以当然不会处理队列消息和输出日志信息了。jstat的输出如下: S0 S1 E O P YGC YGCT FGC FGCT GCT 使用jmap导出这时候的Java堆栈,命令: jmap-dump:format=b,file=29389.hprof 29389。将得到的dump文件放到MAT(EclipseMemory Analyzer)里进行分析,发现很明显是QueueingConsumer持有大量对象导致JVM内存溢出,截图如下: 上网搜索了下,发现有人遇到了类似的问题:RabbitMQ QueueingConsumer possible memoryleak 。解决办法是调用Channel的basicQos方法,设置临时内存中最多保存的消息数。这个数值的设置建议参考 《Some queuing theory: throughput, latency andbandwidth》 权衡决定。 拍脑袋将basicQos设置为16后重启服务,队列终于开始消化了。用jstat观察JVM内存使用情况,也没有再出现剧增溢出的现象。 总结:使用RabbitMQ的时候,一定要合理地设置QoS参数。我感觉RabbitMQ的默认做法其实是很脆弱的,容易导致雪崩。“Youhave a queue in Rabbit. You have some clients consuming from thatqueue. If you don't set a QoS setting at all (basic.qos), thenRabbit will push all the queue's messages to the clients as fast asthe network and the clients will allow.“。这样如果由于某些原因,队列中堆积了比较多的消息,就可能导致Comsumer内存溢出卡死,于是发生恶性循环,队列消息不断堆积得不到消化,彻底地悲剧了。
--------------------------------------------------------------------------
[root@mail ~]# jstat -gcutil 29389
100.00 0.00 100.00 100.00 59.59 1639 2.963 219078 99272.246 99275.209
--------------------------------------------------------------------------
阅读全文
0 0
- 解决RabbitMQ队列超长QueueingConsumer导致JVM内存溢出的问题
- 解决Bitmap导致的内存溢出问题
- JVM成长之路,记录一次内存溢出导致频繁FGC的问题排查及解决
- JVM内存溢出导致的CPU过高问题排查案例
- 解决RabbitMQ队列超长QueueingCons…
- Tomcat 的JVM 内存溢出问题的解决
- Tomcat 的JVM 内存溢出问题的解决
- tomcat 的jvm 内存溢出问题的解决
- JAVA开发(4) -JVM 内存溢出问题的解决
- 导致内存溢出的原因有哪些?内存溢出问题又如何解决
- JceSecurity/BouncyCastleProvider导致JVM内存溢出、CPU过高问题排查
- JVM内存溢出的解决思路
- tomcat 的jvm 内存溢出问题的解决及JVM性能调优
- JVM:内存溢出问题
- jvm内存溢出问题
- 解决内存溢出的问题
- Android---加载图片 解决图片过大导致的内存溢出问题
- 解决因数据库一次查询数据量过大导致的内存溢出问题
- zookeeper和kafka
- Spring思维导图,让Spring不再难懂(cache篇)
- LeetCode-11-Container-With-Most-Water 贪心
- DynamicResource与StaticResource的区别 下面用例子更详细地说明DynamicResource与StaticResource的区别。 先看看这段XAML代码: // Li
- unity中的reflectionProbe的使用
- 解决RabbitMQ队列超长QueueingConsumer导致JVM内存溢出的问题
- 各银行 哈哈
- 3DES加密算法
- 一个高效的数据分页的存储过程
- Javascript使用postMessage对iframe跨域通信
- Java虚拟机-JVM各种参数配置大全详细
- zabbix 自动发现Discovery无法获取主机
- Django01-安装和示例
- 时间倒计时插件