前情概要
4月份某天下午刚上班,春困之际,整个人还不是非常的清醒,结果钉钉开始收到告警,线上一台服务在非常频繁fullGC,一下子,整个人清醒多了,这个不是一个简单的告警,对服务的影响非常大。确实如此,没过几分钟,下游服务开始调用超时告警
我们公司内部的APM工具是pinpoint,可以看到服务超时13:50~14:03这段时间内服务响应时间有很多超过了5000ms
找到出问题的那台"那台实例
红线表示fullGC,基本上这个实例处于不可用的状态,分发到这个实例的请求基本上也就是超时,其他实例此时正常,我们服务总共部署了五个实例,只有这个实例出了问题
快速恢复
- 下线出问题的实例,记得这里先dump堆文件
问题分析
-
原因分析
-
根据以上现象,猜测应该是某个不常用的请求或者某种特殊的场景导致内存加载了大量数据,正好这个请求是由出问题的这个实例来处理的。
-
因为服务了过了一会就恢复了正常,服务日志里也找不到任何的有用的信息,分析陷入了瓶颈,但这个问题只要出现一次,就会导致服务基本上不可用,所以还是要找到根本的原因,彻底的根治这个问题,避免后续产生更大的影响。
-
我们的服务加载数据的途径有限,要么是数据库查询,要么是外部接口返回,根据dump文件其实可以看出来对象其实大部分都是我们内部的实体对象(这里忘记截图了),所以应该是数据库查询返回了大批量数据。
-
解决思路
-
JVM参数调整: 调整JVM参数,尽可能避免出现该问题
-
代码逻辑调整: 找到问题代码并修复
JVM参数调整
整个调整的思路是尽可能最小化"短暂对象"移动到老年代的数量,避免老年代快速膨胀,触发majorGC或者fullGCÿ