线上报警,持续收到cpu使用过载,打开cap系统(京东自研服务器监控)查看,cpu使用情况,如图:已经接近100%
cpu监控开始处理问题:步骤如下
登入堡垒机
第一步,使用top命令
执行top命令,如图示:找到java进程
top执行结果执行 top –p 138209 –H,找出%cpu值很大的,那个情况下一般都比其它线程超过很多,比如下面的32%,然后拿到 第一列的线程ID,比如 48409这个PID。进一步将这个值转化成十六进制。printf 0x%x 48409 在一个linux系统下执行这个即可输出十六进制的数值。当然也可以使用计算器,哈哈。
第二步,打出jstack 文件(这个要快,尽可能跟top命令执行的同时进行)
执行命令 jstack 即可,后面不要跟任何参数,常见的后面经常跟的参数 比如 jstack –F –l,在这里都不用。执行一个不带任何参数的jstack。将这个jstack文件通过文本编辑器打开如下:然后通过刚才 第一步中转换的十六进制数值,在这个文件里面搜索,当时搜索到的一个线程是正在处理GC,而且当时
几个cpu使用率在30%以上的都是在做GC任务。
第三步,打出内存的dump文件
执行命令,jmap -dump:format=b,file=/export/Logs/anycall.jd.local/HeapDump.bin;拿到这个dump文件后,通过MemoryAnalyzer.exe工具将其打开。
说明一点,这个工具默认打开的文件大小为512M,如果dump文件过大,需要修改这个值,找到安装目录下的这个文件MemoryAnalyzer.ini,修改,如下图:
mat分析结果1打开dump文件的图示如下:可以看到有个对象,占据了92%的大小,
mat分析结果2进入,Dominnator Tree视图,可以发现那个线程占据的内存对象最大,如图示:有一个大量的VO对象。
mat分析结果3点击 See stacktrace后,进入线程栈的视图,如图:已经说明了那个类,那个文件持续的加载了这个文件。
mat分析结果4到了这里定位到了问题出现的范围,实际上也告诉你哪些逻辑上出了了问题,那么具体的哪段代码导致的还要根据这个范围和提示继续分析。
回归代码这两次出的问题,一次是因为全量查表,一次是因为递归查es。
使用动态sql的时候,如图:如果组合条件都为空,而且你有没有防卫性的校验判断,就会导致全量查表,这是一种情况。
使用递归,而且递归跳出条件又没有处理,相当于写了个死循环,持续扫描es,加载到内存中,这是一种情况。
大量创建新对象,大量GC线程在跑。
最后定位问题,修改,上线,解决cpu使用率过高的问题。
转载请注明出处,并附上链接,尊重创作。
最好的喜欢方式 是 点击 关注
网友评论