背景
同事反馈生产环境网站突然无法访问,提示错误码“500”。
运维介入排查日志
因该项目业务系统架构较老,使用传统运维手段排查
查看k8s pod状态
1. 确认 OOM 问题
- 查看 Pod 状态:使用
kubectl get pods查看 Pod 列表,注意状态为OOMKilled的 Pod。 - 查看 Pod 详细信息:使用
kubectl describe pod <pod-name> -n <namespace>查看 Pod 的详细描述,包括事件和状态变化,特别注意 OOM 相关的错误日志。
2. 查看pod 日志
- 查看pod日志:kubectl logs
pod -n <namespace>
查看k8s pod log:
日志如下:关键字java.lang.OutOfMemoryError: Java heap space
{"log":"org.apache.logging.log4j.core.appender.AppenderLoggingException: java.lang.OutOfMemoryError: Java heap space\n","stream":"stdout","time":"2024-10-15T00:53:21.505738832Z"}经排查确认问题原因
pod OOM 内存溢出,导致pod不断重启。
解决优化手段
临时调整
1. 检查 Pod 资源限制
- 查看资源限制:在 Pod 的 YAML 配置文件中,检查
resources字段下的limits和requests设置,特别是memory字段。这些设置限定了 Pod 可以使用的最大和最小内存量。 - 调整资源限制:如果发现资源限制设置过低,可以根据应用的实际需求调整这些值。推荐修改 Deployment 或 StatefulSet 等控制器的配置,然后滚动更新 Pod。
2. 检查jvm 限制
- 检查jvm配置
- 调整jvm自由限制:
java -Xms1g -Xmx2g -jar app.jar
如果问题缓解,说明堆内存不足是直接原因,但需深入分析为何内存需求高。
后续优化手段
1. 分析内存溢出原因
1.参数:
java -Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump.hprof -jar app.jar
2.触发条件:
OOM 时自动生成 .hprof 文件。
3.手动生成:
jmap -dump:live,format=b,file=dump.hprof <pid>
:通过 jps 或 ps -ef | grep java 获取。
2.分析堆转储
1.工具
1.Eclipse MAT(Memory Analyzer Tool):
打开 dump.hprof,分析内存占用。
2.JVisualVM:
加载堆转储,查看对象分布。
2.分析步骤
1.查看概览:
MAT 的 “Dominator Tree” 或 “Histogram” 显示占用内存最多的对象。
示例:
| Class Name | Shallow Heap | Retained Heap | Percentage |
|---|---|---|---|
| java.util.ArrayList | 24 | 10,485,760 | 50.12% |
内存。
2.查找大对象:
检查 java.util.ArrayList、byte[] 等常见大对象。
3.检查引用链:
在 MAT 中右键对象 -> “Path to GC Roots”,找出谁持有引用。
示例:某个缓存类(如 HashMap)未释放。
4.泄漏嫌疑(Leak Suspects):
MAT 自动生成报告,指出可能的内存泄漏点。