记第二次线上问题排查过程

9.14早上八点多服务开始频繁重启,影响到线上,记录一下整体排查过程。

1.首先看到pod的CPU 负载较高,以为是流量增大导致CPU打满,线程处理不过来,探针探活失败导致重启,第一次解决办法增加CPU核数,未解决;
2.看pod拉起来时候的日志报错信息,发现有kafka的报错,抛出了自定义的异常类,进入代码查看,consumer是手动提交,且只catch了IOException,自定义异常会出现无法提交offset。推测是consumer卡死,导致pod的CPU打满重启。第二次解决办法:在consumer中catch所有Exception。但是看topic监控,并没有出现大批量消息阻塞。修改上线后仍旧未解决;
3.通过skyWalking发现pod的old GC频繁,且eden区内存打满,推测是发生了OOM。进一步检查,指定堆大小的时候,设置了最大最小堆内存为3G,但是年轻代设置了2G,可能是参数不合理。第三次解决办法:增加pod内存至8G,堆内存至5G,同时优化配置参数,不显式指定年轻代大小。结果:未解决;
4.在第三次解决过程中发现pod拉起来后会平稳运行一段时间,至某一时刻堆内存突增直接打满,然后会进行old GC,之后就是pod重启。解决办法:下载下来堆内存文件,用工具进行分析,看具体是哪个对象占了大量内存。具体操作步骤:①服务构建镜像时选择的必须是jdk不是jre,否则无法识别jmap命令;②pod内执行命令jps,找到自己服务对应的进程号;③执行jmap -dump:format=b,file=<文件名> ;④堆文件生成后执行命令python -m SimpleHTTPServer 端口号,开通http访问;⑤在浏览器地址栏通过http://pod的IP:④中端口号/文件名开启文件下载;⑥通过MAT软件打开堆文件,分析泄漏报告;通过报告发现是一条mongo查询语句导致OOM,具体就是查询了所有手机号为空的用户,数据量太大导致程序崩掉。解决方法:判断查询条件,结果:解决重启问题。

最后分析本次事故原因:1.代码漏洞,Map map = new HashMap<>();
String s1 = String.valueOf(map.get(“test”));String s2 = (String)map.get(“test”);
这段代码里s1=”null”,s2=null;这就造成了最后对字符串判空时用s1判断成了非空,但是查询的时候用的又是s2出现了上述问题;2.前端上线,导致这种情况变多,频繁重启;

总结:1.重要的在线服务建议和运维沟通,做好文件挂载,不然会出现堆文件生成了,但是pod重启,文件下载被中断;2.出现问题时,先看日志,有明显报错先解决报错问题,如果不行,及时观察skyWalking,看是CPU还是OOM,如果是OOM,则需要尽快下载有问题时刻的堆文件进行内存分析,定位问题。

你可能感兴趣的:(日常工作问题,java)