https://blog.csdn.net/qq_37722071/article/details/121091251
酝酿了很久才开始写这篇文章,实际就是记录一次线上问题处理的过程。在我们的日常工作中每天都会处理各种各样的问题,像线上环境内存飙高,服务出现频繁fullgc这一的问题也是面试中常见的问题,但是我们日常的开发中其实很少能遇到,故在此记录一下本次问题定位处理的过程希望能为大家遇到类似问题的时候提供一些参考。
1、背景介绍
问题出现在我们线上运行的一个soa服务,这个服务为商家端和审核端提供对应的业务,作为电商核心的商品系统每天也有不小的流量,同时也是一个运行多年的老系统存在着各种各样的小问题,整体架构为接入层对外提供rpc接口,service做逻辑处理,底层数据源使用mongodb。
2、问题发现与定位
问题出现在一个工作日的上午,系统监控不时的出现性能告警,并且线上也有用户反馈系统存在超时异常的现象。通过性能监控发现出现问题时总是有其中一台容器性能异常飙高(监控现象如下图),且每次都不是同一台容器,由此分析不是单台容器出现问题,是应用层逻辑有问题导致。
通过分析出现问题的机器发现每次性能飙高的同时容器也会出现cpu使用率高和网络流入高的告警而系统量较其他时段没有太大的变化,此应用并非cpu密集型应用,此时矛头就指向了gc,查看jvm监控发现在出问题的时段应用堆内存突然升高与此同时出现了大量的fullgc。
上面的监控我们发现了一个奇怪的想象,对内存突然飙高并且fullgc无法正常回收,所以出现持续二十多分钟的频繁fullgc。由此我们分析一定是存在大对象直接进入了老年代且存在持续的引用导致gc无法正常回收。到这时这个问题的处理脉络已逐渐清晰,我们只需要找到是哪些对象导致的,问题就引刃而解了。我们在出现问题的容器上将dump日志记录下来,通过mat工具分析dump日志发现有一个对象占了3个多G,那么罪魁祸首一定是它了。
通过引用关系继续向下排查,看到是有个ProductApply的List占用了3个多G。
结果如下:
看到执行线程发现时有一个rpc的线程,通过mat的Thread\_Overview看看这个线程干了什么。