新生代内存分配低导致瞬时CPU高
收到告警
我们在日常运维中使用Prometheus进行系统监控,并配置了一系列告警规则来及时发现和处理异常情况。最近,我的飞书收到了Prometheus发出的告警消息,提示OA系统服务器的CPU负载较高。以下是告警详情:
告警类型:OA系统_NODE_node_overload
开始时间:2024-08-24 20:10:48
结束时间:0001-01-01 00:00:00(表示告警尚未结束)
故障主机IP:xxx xxx
告警信息:OA机器 CPU 负载较高
节点名称:node-oa
排查原因
收到告警后我立即登录服务器进行排查,首先使用top命令:
CPU 使用情况:3.2% 用户态 (us),0.6% 系统态 (sy),95.5% 空闲 (id)
内存使用情况:总计 32GB,已用 16GB,空闲 330MB
Swap 使用情况:总计 8GB,已用 2.7GB,空闲 5.6GB
当前CPU使用率并不算高,感觉是存在短时峰值或其他问题,所以接下来使用Arthas进一步排查。
使用dashboard命令:
咋一看除了非堆内存有点高,好像没有啥问题,于是我继续观察,突然我发现gc.parnew.count在一次刷新中增加了3次,也就是5秒钟执行了3次minorGC,同时我又收到了飞书的告警,继续观察发现eden区使用率增长的很快,并且minorGC很频繁,于是我猜测是频繁的minorGC导致瞬时CPU高。
解决问题
查询资料:新生代(1/3)、老年代(2/3),新生代分Eden(8/10)、From Survivor(1/10) 、To Survivor(1/10)这样分配比较合适,于是着手进行优化。
在原来的jvm参数中添加-Xmn2048m:
-Xmx7550m
-Xms5120m
-Xmn2048m
-XX:ParallelGCThreads=20
-XX:+UseConcMarkSweepGC
-XX:-OmitStackTraceInFastThrow
-XX:+UseParNewGC
-XX:+DisableExplicitGC
-Djdk.tls.ephemeralDHKeySize=2048
-Dfile.encoding=GBK
-Xss256k
-XX:PermSize=256m
-XX:MaxPermSize=512m
-XX:ReservedCodeCacheSize=512m
调整jvm参数后持续观察了一周,发现cpu使用率正常,飞书告警也没有推送了,成功解决了问题。
总结
优化前:
1.新生代:(1331 + 166 * 2) / 7383 = 23%
2.minorGC:4120188 / 74124 = 55.59ms
3.majorGC:47246 / 45 = 1049.91ms
优化后:
1.新生代:(1638 + 204 * 2) / 7345 = 28%
2.minorGC:208624 / 6831 = 30.54ms
3.majorGC:2721 / 9 = 302.33ms
通过计算对比:新生代占比由23%提升到28%,minorGC的平均时长减少了20多毫秒,majorGC的平均时长减少了700多毫秒。
仅仅添加了一个jvm参数,性能提升竟如此巨大。