一次JVM内存泄漏的简单记录

回到首页☞

由于外包无外网权限,信息安全决定法律问题,所以详细内容不粘贴,只是记录大体流程。

1、问题描述

EC2反馈主机创建失败,定位发现前置机出了问题。
基本链路是:ELB+openresty+tomcat(4)
4个tomcat 分别部署在4个独立的VM上,堆内存设置为4G.

2、问题定位

2.1 top

查看cpu 300%~700%的来回跳动。

2.2、tail catalina.out

发现内存溢出

2.3、kill 进程重启

一分钟不到内存溢出

2.4、jmap -histo pid

查看内存使用情况
[C 位列第一把交椅,3.5G的内存占有量。
也就是String爆了。
怎么分析?
看了下业务相关的类就是kafka较多。

2.5、分析kafka使用情况

MQCLIENT+ZK 4个topic80监听200分区*50线程池。
xxs配置的1024k,难道是kafka消费程序爆掉了。
尝试方案:
kafka jar升级,去除threadpool,完全采用监听实例消费,80个降低一半40个,重启服务。
依然一分钟后挂掉。

2.6 dump

在tomcat启动参数中加入两个参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data01/tomcat/oom.hprof

启动tomcat 内存就会爆掉,获取oom.hprof 二进制文件,ftp到本地。

2.7 JDK工具jvisualvm

jvisualvm:功能强大的控制台
导入 oom.hprof 文件
直接点击内存泄漏的线程,查看日志。

setLog 接口爆掉了。

2.8 内存泄漏继续分析

大量请求并没经过tomcat,已经在nginx+redis直接分流了,setLog是返回任务状态,其实请求量不大,只是可能会出现日志内容较大,导致post请求的body非常大。
setLog直接爆掉,说明有些特殊任务日志在2G以上。
setLog做了大小控制,>16M 不再写Mongodb,但是请求进入了Tomcat,导致JVM挂掉。

再次查看catalina的日志,发现有三台私有云主机自动上报日志后直接挂掉。

2.9 确诊日志是否超大

通过自动化快速平台下发任务去查看日志大小。

cd /tmp/.....
ll -th

三台私有云主机中的未上报日志任务的日志分别有:
>2G
>3G
>4G

2.10 先清理日志确保生产正常

cd /tmp/.....
>job.log

2.11 确认处理方案

1、最好的方案是升级agent
旧的agent是有缺陷的,在web后台程序中做日志拦截意义不大,因为进入tomcat就会爆掉。
最好的方案是在agent的pyhon程序中直接做日志过滤,大于某个值例如10M就不要上报了。
如果有人下发自动化任务

select * from table

一个10G的表内容作为日志返回,会让真个平台挂死,是非常大的漏洞。

但是修改agent虽然把逻辑写入了最底层,os端但是全量升级云主机风险非常大。

2、nginx限流
openresty除了做了很多代理,和分流,其实还可以限流限量。

2.12 用nginx配置做快速方案

client_max_body_size 10m;

别看这么一个小小的参数,确实是系统安全的一个保障。
并且只设置在setLog这个请求上,不会影响其他请求。getJob 还是可以下发超过1G以上的软件安装任务。

3、小结

这种问题遇到不容易,确实是个经典案例。
但是修改agent才是最根本的解决方案,让agent更健壮,虽然有全量覆盖的压力和风险,真心想把平台做强,必须迎难而上。
当然如果你是外包,还是以政治为主,必须按照领导想法来。

回到首页☞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值