Skip to content

生产事件

1、线上 pod OMM

1.1、问题描述

image-20230721171634888

容器stable/mdm-territory-svc-latest-56db9dbbb9-n8sw7 发生OMM 自动重启

1.2、问题定位

  1. pod中java服务 territory-svc JVM参数如下:

    image-20230721173900736

  2. 已配置-XX:+HeapDumpOnOutOfMemoryError,当发生内存溢出时,会自动dump文件。

  3. 运维工具将dump文件推送至OSS

  4. OK! 那我们直接把DUMP文件下载下来,分析一下!

image-20230721172159999

将DUMP文件导入MAT进行分析

image-20230721172247250

到这里能大概猜测到是在操作数据库的时候数据量太大导致堆内存溢出

通过Histogram定位大内存对象

image-20230721172442785

这里发现了一个我们业务中定义的对象 com.softium.territory.tery.po.TerritoryDepartmentPO

通过tread_overview定位线程

image-20230721172610335

image-20230721172732275

image-20230721172746177

查看线程堆栈 这里我们可以通过搜索 业务代码中的包名 来定位业务代码

image-20230721173029986

到这里我们定位到出现问题的代码了 我们看一下这段代码

image-20230721173329345

显然,这里查询数据库时遇到极端条件,导致大量数据查询甚至全表查询,方法内返回的 List TerritoryDepartmentPO对象很大

1.3、解决方案

代码优化

image-20230721174144645

image-20230721174157701

image-20230721174400683

image-20230721174555334

1.这里返回参数需要的只有 productIds ,显然没有必要去查表的所有字段

2.jvm内存去重 改为数据库去重 ,把压力传递给数据库

3.查询命中了数据库索引了,虽然这次的问题瓶颈不在数据库,这里我们只返回product_id字段后 使用了 索引下推 ,顺便给数据库做了一波优化

JVM优化

考虑是否要重新合理分配一下 该POD JVM 堆内存

-Xms2048m -Xmx4096m

解决问题!