生产事件
territory-svc OMM
1.1、问题描述
容器stable/mdm-territory-svc-latest-56db9dbbb9-n8sw7 发生OMM 自动重启
1.2、问题定位
pod中java服务 territory-svc JVM参数如下:
已配置-XX:+HeapDumpOnOutOfMemoryError,当发生内存溢出时,会自动dump文件。
运维工具将dump文件推送至OSS
OK! 那我们直接把DUMP文件下载下来,分析一下!
将DUMP文件导入MAT进行分析
到这里能大概猜测到是在操作数据库的时候数据量太大导致堆内存溢出
通过Histogram定位大内存对象
这里发现了一个我们业务中定义的对象 com.softium.territory.tery.po.TerritoryDepartmentPO
通过tread_overview定位线程
查看线程堆栈 这里我们可以通过搜索 业务代码中的包名 来定位业务代码
到这里我们定位到出现问题的代码了 我们看一下这段代码
显然,这里查询数据库时遇到极端条件,导致大量数据查询甚至全表查询,方法内返回的 List TerritoryDepartmentPO对象很大
1.3、解决方案
代码优化
1.这里返回参数需要的只有 productIds ,显然没有必要去查表的所有字段
2.jvm内存去重 改为数据库去重 ,把压力传递给数据库
3.查询命中了数据库索引了,虽然这次的问题瓶颈不在数据库,这里我们只返回product_id字段后 使用了 索引下推 ,顺便给数据库做了一波优化
JVM优化
考虑是否要重新合理分配一下 该POD JVM 堆内存
-Xms2048m -Xmx4096m
解决问题!