应用执行一段时间后响应不了外部请求
排查步骤
1.立马top一下看应用状态发现CPU一直在50%-70%飘荡,结果如下:
2.然后猜测GC可能存在问题,立马jstat -gcutil 1 1000 1000打印GC情况得到如下结果:
3.看到old区满了,立马jmap下dump文件,通过工具分析得到如下结果:
4.发现是开源框架jaeger的问题,我司对jaeger做了层包装,故去查阅源码发现,我司对jaeger里的io.jaegertracing.internal.JaegerSpan包装修饰成了常量,根据jvm基础知识我们知道常量会被当成GCroot一直回收不了,故虽然外层用了threadLocal的弱引用修饰,但是没发现threadLocal.remove()的主动调用,所以依然被GC回收不了,故一直撑爆OLD区到100%,引发频繁Full GC,拉高机器CPU,使得外界请求无法及时响应。结果如下:
5.但是,因为当时临近下班时间,被老板拉去聚餐吃饭,忘记处理这个生产问题情况,第二天早上上班后发现诡异情况,机器在昨晚22:30分突然CPU使用量降了下来,频繁Full GC也停止,但是外部请求依然进不来,情况如下
6.故jstack打印堆栈信息查看情况,发现所有logback的线程都是WAITING (parking)状态,阻塞对象都是叫0x00000000b0c0cbd8的对象,所有的http-nio请求也都是WAITING (parking)状态,阻塞对象都是叫0x00000000b2be1708的对象,故怀疑是jaeger调用链收集昨晚异常,所以所有logback线程都处于阻塞状态,以至于引发所有正常http-nio线程阻塞,依然响应不了外界请求。致辞赶紧重启,之后应用恢复正常。现场结果如下: