某线上项目Tomcat CPU飙高分析及处理

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

背景

该项目是某单位的一个话务系统,基于ssh的单体项目,已经运行好几年。公司协助升级部分功能,但在重新部署后,每到高峰期电话增加,就会出现cpu飙高导致宕机。

一阶段问题排查

  1. 通过top命令可以定位该应用占用cpu飙到300%,占用内存达到3.8G。
  2. 通过过top -Hp pid 命令,可以定位到占用cpu最高的几个线程。
  3. 配合jstack查看对应线程(第2步获取id),可以看到占用cpu最高的线程都是垃圾回收线程。
  4. 通过jmap -dump:live,format=b,file=/opt/tmp/test.hprof pid获取堆内存转储文件
  5. 通过jvisualvm和mat进行分析发现关键问题如下图
  6. 定位关键字QueryPlanCache,查阅资料得知hibernate中的QueryPlanCache会缓存sql,以便于后边的相同的sql重复编译。如果in后的参数不同,hibernate会把其当成不同的sql进行缓存,从而缓存大量的sql导致heap内存溢出。QueryPlanCache默认2G.
  7. 通过jinfo查看jvm最大的堆内存是4G.
    在这里插入图片描述

一阶段分析及处理结果

分析是由于堆内存不足,系统运行需要接近2G加上hibernate缓存2G刚好达到堆内存的最大值附近。当高峰期内存往上飙升,但堆内存不足,于是触发垃圾回收,但刚回收的内存马上又被用光,于是不停触发垃圾回收。导致垃圾回收的线程不停抢占cpu,最终导致宕机,但是没有想到从垃圾回收的层面来查看问题,如果当时可以通过jstate -gc ip 命令来查看垃圾回收的频率,可能会更快找到问题。

处理方式

增加最大堆内存的大小

结果及总结

堆内存增加以后,cpu飙高不再出现。但运行2天后又会出现系统宕机的问题,

二阶段问题排查

  1. 查看日志发现too many openfiles 异常。
  2. ulimit -a 看到当前的最大连接数是1024。
  3. 修改最大连接数后,过几天还是会不够,经观察,连接数是不停增加的,显示应该有忘记关闭的连接。
  4. 通过netstat -anop ip可以查看该进程建立的连接数。原来是程序员调用redis后忘记进行close。修改后问题处理完成。

处理方式

redis连接正确释放。

结果及总结

问题处理完成,良好运行。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值