容器下Java应用问题排查步骤
总结摘要
容器下Java应用问题排查步骤
1 基本信息收集
明确应用的JDK 版本,不同JDK版本参数配置有差异。
- 尤其是低版本JDK切换到>=JDK1.8中,永久代变为元空间对应的控制参数发生变化。
目前应用的运行状况是什么?
- 是内存居高不下,内存缓慢增加还是进程突然宕掉?(或者是应用卡死还是自动重启了?)
- 现象发生的节点,近期有无配置变更、有无版本升级、有无应用本身的相关监控数据。
2 保留现场
如果条件允许不建议直接重启或者回滚,可以先保留现场,需要保存如下内容。
2.1 Linux日志
用于分析VM层面的OOM情况。如果观察到应用Docker已经宕掉或者重启,有概率是被linux oom_killer kill掉。
| |
2.2 当前JVM启动参数
2.3 查看内存状态(jstat)
| |
2.4 查看内存状态(arthas)
| |
2.5 查看内存状态(jcmd)
- 调整jvm参数开启特性,加入参数 :-XX:NativeMemoryTracking=summary 或者 -XX:NativeMemoryTracking=detail(NMT必须先通过VM启动参数中打开,不过要注意的是,打开NMT会带来5%-10%的性能损耗)
- 快速检查内存使用summary;排查native 内存泄露使用detail,生产环境建议使用summary。
- 查看内存报告命令
- 报告解读
| |
2.6 导堆(heapdump 文件)
注意,如果应用运行正常,此操作会导致应用短时间卡死,请慎重操作。
| |
2.7 建议设置GC日志打印
2.8 建议设置输出错误日志
2.9 内存栈
2.10 查看未关闭的文件句柄
| |
2.11 Java 日志
如果是JVM内存溢出,一般是会打出相关日志。如果日志较为明确,可以帮助我们快速定位问题。比如:
- 元空间溢出:java.lang.OutOfMemoryError: Metaspace
- 直接内存溢出netty会报OutOfDirectMemoryError: failed to allocate capacity byte(s) of direct memory (used: usedMemory , max: DIRECT_MEMORY_LIMIT )。
较为常见的是堆内存溢出:java.lang.OutOfMemoryError: Java heap space
| |
2.12 查看请求来源
无相关调用方日志辅助定位时,通过tcpdump定位请求来源 Tcpdump 详解(抓包)_tcpdump抓包命令-CSDN博客
| |