[CPU飙升排查]生产CPU飙升,YGC不断的事故
背景
最近给上线还未使用的服务配置监控,监控系统电话将我呼醒 ,导致原本就不多的头发一阵掉落.
还好系统还没有流量进入,先免打扰,第二天再处理.
查看面板情况如下:
FGC正常
YGC不断
CPU飙升
思路确定
分析了下YGC不断,但是没有FGC,CPU飙升,可能出现的情况是哪里有活锁或者死循环了,
这种情况下垃圾是可以被回收的,但是会源源不断地在新生代产生垃圾.
接下来就是申请容器权限,进入查看
Jdk工具使用
Jmap查看下占用高的有没有认识的
1. 运行jcmd,查看java进程id
2. 运行 jmap -histo 22 | head -20 ,查看占用高的类
一般jmap运气好能看到到一个业务类,这种情况下基本能定位到代码在哪里,
但是无意外没看到熟悉的类.
查看线程CPU占用情况
1. 运行 Top -Hp 22 -n 3,查看占用线程
2. printf '%x' 56, 将56转成16进制
3. jstack 22 | grep -A 100 0x38 , 用0x38在java线程栈里搜索,看看什么情况
最麻烦的情况来了,根本没有业务类,框架的问题,接下来只能上arthas了
Arthas使用
1. 下载解压arthas,解压,attach进程
去官网下载arthas https://arthas.aliyun.com/doc/
并且解压 运行 java -jar arthas-boot.jar attach
输入1 进入命令行
2. thread -n 3 列出占用最高的几个线程
毫无意外 和top -Hp 的结果一样,但是方便一些
3. watch org.springframework.boot.loader.jar.JarURLConnection get,watch下方法在干什么
4. tt -t com.taobao.remoting.util.SharedResourcesInit getResource ,根据调用栈执行方法监控
tt -t 一般用于监控某一个方法的调用记录,如果调用多此会出现多条记录,
可以看到方法无返回,抛出异常了
4. tt -i 1200,选择上面tt -t的一个序号显示详细信息
可以看到抛出java.lang.NoClassDefFoundError
5. 发现生产缺少依赖
根据Maven依赖分析
发现缺少mina-core
有个包在缺少依赖的情况下不停一遍遍在connect
总结
在业务代码Bug的情况下,一般jdk提供的工具就可以分析出代码问题,
但是框架型的问题,需要借助arthas等修改字节码的技术attach进去查看具体情况(感兴趣实现的可以参考我写的代码段里有个简单的代理).
还有要吐槽的,这种框架明明是强依赖的,应该启动报错,而不是业务代码能跑
但是占用CPU形成一个死循环.