问题产生:
首先问题是这样的,周末收到了线上报警,发现cpu占用达到了90多,上平台监控系统查看容器,在jvm监控中发现有一个pod在两个小时内产生了48次youngGc一次fullGc,这个问题特别严重且少见,由于我之前也没有排查过此类问题,所以也是百度。
问题分析:
首先异常gc的情况只出现在一个pod上(系统有多个pod),在监控系统找到对应的pod,进入pod内部查看问题原因。
1、进入pod之后,输入top查看各linux进程对系统资源的使用情况。
2、输入top -H -p pid 通过此命令可以查看实际占用CPU最高的的线程的id,pid为刚才资源使用高的pid号。
3、出现具体线程的资源使用情况,表格里的pid代表线程的id,我们称他为tid。
4、使用命令printf "%x\n" tid,将线程tid转换为16进制。
5、因为我们线程id号在堆栈里是16进制的所以需要做一个进制转换。
6、输入jstack pid | grep 2ea >gc.stack
jstack是jdk给提供的监控调优小工具之一,jstack会生成JVM当前时刻的线程快照,然后我们可以通过它查看某个Java进程内的线程堆栈信息,之后我们把堆栈信息通过管道收集2ea线程的信息,然后将信息生成为gc.stack文件。
7、先cat gc.stack 发现数据有点多在容器里看不方便,于是我下载到本地浏览,因为公司对各个机器的访问做了限制,我只能用跳板机先找到一台没用的机器a,把文件下载到a然后我再把a里的文件下载到本地(本地访问跳板机OK),先输入python -m SimpleHTTPServer 8080,linux自带python,这个是开启一个简单http服务供外界访问。
8、然后登录跳板机,使用curl下载curl -o http://ip地址/gcInfo.stack,下载完毕
记得关闭python开启的建议服务。
9、把文件下载到了本地,打开查看编辑器搜索2ea,找到nid为2ea的堆栈信息。