首页 > 编程语言 >Kubernetes-POD生成 java dump文件

Kubernetes-POD生成 java dump文件

时间:2024-09-20 14:47:15浏览次数:9  
标签:java Kubernetes dump OOM 重启 生成 heap logs

目录

背景

在今天的线上业务中,某服务频繁重启。经过排查日志和事件信息,确认是由于 OOM(Out of Memory)导致服务重启。为了方便研发团队定位 OOM 的具体原因,我们决定在 OOM 发生时自动生成内存快照(heap dump),供后续分析使用。

关于 OOM 的详细介绍,可以参考这篇博客:https://www.cnblogs.com/klvchen/articles/12448436.html

JVM 提供了一些参数,能在发生 OOM 时自动生成 heap dump:

  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:HeapDumpPath=/logs/heapdump.hprof

然而,目前还存在两个问题:

  1. 多次重启可能导致 heap dump 覆盖。例如,如果程序发生了两次 OOM,第二次生成的 heap dump 会覆盖第一次的。
  2. 这个参数仅适用于 JVM 内部的 OOM,而 K8s 主动重启服务时并不能生成 heap dump。我们通过 kubectl describe pod 查看重启原因,发现是因为健康检查未响应,K8s 自动重启服务。这类情况并非 JVM 的 OOM,因此上述参数无法帮助生成内存快照。

为了解决 K8s 重启时无法导出 heap dump 的问题,我们可以通过配置 preStop 钩子,在容器停止前生成内存快照。相关命令如下:

  1. 获取进程 ID 为 10 的程序的堆栈信息:
jstack -F 10 >> /logs/thread.dump
  1. 生成堆内存快照:
jmap -dump:format=b,file=/usr/src/logs/dump.hprof 10

通过这样的优化,既能避免 heap dump 被覆盖,又能在 K8s 重启时生成有用的内存快照,帮助排查问题。

配置钩子函数

在command增加

jstack -F $(jps |grep -v Jps | awk '{print $1}') | tee -a /usr/src/logs/thread.dump && jmap -dump:format=b,file=/usr/src/logs/$(date +'%Y-%m-%d_%H%M%S').hprof $(jps |grep -v Jps | awk '{print $1}')"
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "curl -X PUT \"http://eureka-service:8761/eureka/apps/${POD_NAME}/${POD_IP}:pi6000-mdl-web:8080/status?value=DOWN\" && sleep 30 && jstack -F $(jps |grep -v Jps | awk '{print $1}') | tee -a /usr/src/logs/thread.dump && jmap -dump:format=b,file=/usr/src/logs/$(date +'%Y-%m-%d_%H%M%S').hprof $(jps |grep -v Jps | awk '{print $1}')"]

验证

手动执行 **<font style="color:rgb(244, 116, 102);">kubectl delete pod xxxx</font>**,可以查看到生成的文件了

标签:java,Kubernetes,dump,OOM,重启,生成,heap,logs
From: https://www.cnblogs.com/Unstoppable9527/p/18422492

相关文章