前言:本文注重的是问题原因的定位,找到问题,解决的方法择优即可,cpu一直飙高的可能性有多种,不同的情况出现的现象和对应的分析方法略有不同,大家可以从中借鉴思路,本次介绍的是-tomcat线程数设置不当导致的。
1,问题现象
监控系统报警,大量的用户访问速度很慢
2,分析及解决思路
常见的cpu高的原因可能有,死循环,死锁,线程池参数设置不当,频繁gc等等。
解决这些问题的思路都很像,主体就是
- 发现问题
- 找到占用cpu资源最多的或前几个的进程
- 找到进程中使用资源最多的线程
- 通过观察线程的类名和方法名(如:java.lang.Thread.State: TIMED_WAITING (parking))最后检查一下出现这个的次数即可定位问题。
注:如果在第三步发现是某一两个线程使用cpu非常多,那么可以直接按第四步分析对应的类和方法即可,如果不是简单一两个,那么最后还是要分析堆栈的文件为主
3,对应的实际操作
上述的思路落实到操作上,是一些命令(具体的操作系统)或者工具,自己对windows的命令不太熟,我这里使用的是jdk自带的–Java VisualVM。
- 工具操作:查看进程的pid(cpu高的),找到对应的服务,具体做法是,查看应用程序–抽样–cpu,找到cpu最高的,查看发现,一直是tomcat的任务队列占用cpu最多,同时u也可以在导出的堆栈文件中找到,大量的线程等待的日志
http-nio-8211-exec-99" #209892 daemon prio=5 os_prio=0 tid=0x000000001d460000 nid=0x274c waiting on condition [0x0000000076bee000]
java.lang.Thread.State: TIMED_WAITING (parking)
查找配置发现:
server:
tomcat:
min-spare-threads: 50
max-threads: 2000
connection-timeout: 10000
max-connections: 10000
accept-count: 1000
(这里就不分析tomcat设置了,感兴趣的可以自己了解),然而实际情况是当这台服务器的tomcat线程达到几百后,就出现大量的线程切换(普通的4核cpu)使用cpu,因此这个显然是在这是不合理的,具体的修改
数值,需要根据压测和实际场景调整,因为是线上的问题,应急处理是开启了一台从服务器做负载均衡。
2. 命令操作,大部分的服务器是linux的,这里就补充一下命令,使用命令做上面的步骤分别是:
top #查看使用cpu资源的排序
top -Hp pid(上一步的) #查看进程下线程的使用资源情况的排序
jstack pid file #file为导出的文件名,自定义即可,例:jstack 10086 10086.txt
cat file | grep -A 20 pid #查看日志文件,注意日志文件中的pid使用的是16进制,例:pid为10086时,cat 10086.txt | grep -A 20 2766
4,总结
最后是自己的一点感悟,上线系统前,前期做好测试和压测,在线上要有动态扩容或者限流的能力,出现问题,谨慎处理,思路清晰,平时多积累,能定位到问题才能解决问题,少写bug,才能减少无意义的加班!!!