一、发明问题
下面是线上呆板的cpu利用率,可以看到从4月8日开始,跟着时间cpu利用率在慢慢增高,最终利用率到达100%导致线上处事不行用,后头重启了呆板后规复。
二、排查思路
简朴阐明下大概出问题的处所,分为5个偏向:
三、开始排查
即通过上述要领没有直接定位到问题。
四、办理方案
1.重启了6台中问题较量严重的5台呆板,先规复业务。保存一台现场,用来阐明问题。
2.查察当前的tomcat线程pid
3.查察该pid下线程对应的系统占用环境。top -Hp 384
4.发明pid 4430 4431 4432 4433 线程别离占用了约40%的cpu
5.将这几个pid转为16进制,别离为114e 114f 1150 1151
6.下载当前的java线程栈 sudo -u tomcat jstack -l 384>/1.txt
7.查询5中对应的线程环境,发明都是gc线程导致的
8.dump java堆数据
sudo -u tomcat jmap -dump:live,format=b,file=/dump201612271310.dat 384
9.利用MAT加载堆文件,可以看到javax.crypto.JceSecurity工具占用了95%的内存空间,劈头定位到问题。
MAT下载地点:http://www.eclipse.org/mat/
10.查察类的引用树,看到BouncyCastleProvider工具持有过多。即我们代码中对该工具的处理惩罚方法是错误的,定位到问题。
五、代码阐明
我们代码中有一块是这样写的
这是加解密的成果,每次运行加解密城市new一个BouncyCastleProvider工具,放倒Cipher.getInstance()要领中。
看下Cipher.getInstance()的实现,这是jdk的底层代码实现,昆山软件公司,追踪到JceSecurity类中
verifyingProviders每次put后城市remove,verificationResults只会put,不会remove.
看到verificationResults是一个static的map,即属于JceSecurity类的。
所以每次运行到加解密城市向这个map put一个工具,而这个map属于类的维度,所以不会被GC接纳。这就导致了大量的new的工具不被接纳。
六、代码改造
将有问题的工具置为static,每个类持有一个,不会多次新建。
七、本文总结
碰着线上问题不要慌,首先确认排盘查题的思路: