问题背景:某项目生产环境正常投用的xx业务系统,在某天下午业务组反馈,xx业务系统客户端及网页版应用均无法登录,请求登录页面无响应。
影响范围:xx业务系统无法使用
排查思路:
一般情况下,Java应用占用CPU较高的原因大部分为以下两种情况:
- 应用属于计算密集型应用
- 应用方法中出现了死循环
排查过程:
1.首先查看系统资源占用信息,使用top看一下,定位到占用CPU较高的进程PID。
top
可以通过ps aux | grep PID命令,进一步确定是否tomcat进程出现了问题。
2.定位最耗cpu的线程,使用ps -mp pid -o THREAD,tid,time | sort -rn命令显示线程列表,并找到占用CPU高的线程。其中 tid代码线程ID,time代表这个线程的已运行时间。
ps -mp 17789 -o THREAD,tid,time|sort -rn
3.将需要的线程ID转换为16进制格式。使用printf "%xn" tid命令,手动将线程ID转换为16进制。
printf "%x\n" 18081
4.打印线程堆栈信息,使用命令Jstack PID | grep tid –A line输出line行线程堆栈信息。
jstack pid |grep tid -A 30
在执行上述命令后会看到如图所示堆栈信息,找到nid=$(tid十六进制值)即可定位出现问题的代码了!
5.接下来再回到代码,分析下具体的代码中的方法。对相应方法进行优化,若无可优化空间,则应进行应用服务器扩容。
问题总结:
经排查,开发人员在xx业务系统中新增了一个报表查询功能,且功能新增后直接在生产环境进行了发版。由于报表查询的查询SQL为添加过滤条件,导致全表扫描,从而使得应用CPU打满。
建议:
建议后期发版过程严格遵守应用发布流程规范,按照研发->测试->上线流程进行应用发布,并在上线前按照规范中的发布申请、发布审批等步骤对应用所需资源、SQL脚本等进行审核。