更新时间:2024-10-18 GMT+08:00
使用通用文件存储(SFS 3.0)自动收集异常退出的JVM转储文件
当您使用Java开发业务时,如果设置的JVM堆空间过小,程序可能会出现OOM(Out Of Memory)问题。为了解决这个问题,您可以使用通用文件存储(SFS 3.0)作为记录日志的载体,并将其挂载到容器内的相应目录中。当JVM发生OOM时,通用文件存储(SFS 3.0)可以将日志记录到相应的目录中。
前提条件
- 已创建CCE Standard集群,详情请参见购买Standard/Turbo集群。
- 使用通用文件存储(SFS 3.0)作为CCE 容器业务存储时,需要先配置VPC终端节点,通过VPC终端节点与通用文件存储(SFS 3.0)建立通信。详情请参见配置VPC终端节点。
操作步骤
- 基于通用文件存储(SFS 3.0)创建一个PVC。
cat << EOF | kubectl apply -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: jvm-sfs-pvc namespace: default annotations: {} spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi storageClassName: csi-sfs EOF
- 使用下面的YAML创建一个Deployment,用于模拟Java服务发生OOM,将产生的dump文件转储到绑定通用文件存储(SFS 3.0)的PV中。
cat << EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: java-application namespace: default spec: selector: matchLabels: app: java-application template: metadata: labels: app: java-application spec: containers: - name: java-application image: swr.cn-east-3.myhuaweicloud.com/container/java-oom-demo:v1 #本文中的镜像仅做示例 imagePullPolicy: Always env: - name: POD_NAME #取metadata.name作为环境变量POD_NAME的值 valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: POD_NAMESPACE #取metadata.namespace作为环境变量POD_NAMESPACE的值 valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace args: - java #执行java命令 - -Xms80m #设置堆内存的最小Heap值 - -Xmx80m #设置堆内存的最大Heap值 - -XX:HeapDumpPath=/mnt/oom/logs #发生OOM时,堆内存转储的路径 - -XX:+HeapDumpOnOutOfMemoryError #捕获堆发生OOM的错误 - Mycode #执行应用程序 volumeMounts: - name: java-oom-pv mountPath: "/mnt/oom/logs" #容器内部使用/mnt/oom/logs做为挂载目录 subPathExpr: $(POD_NAMESPACE).$(POD_NAME) #使用$(POD_NAMESPACE).$(POD_NAME)创建子目录,并将OOM转储文件生成到子目录中 imagePullSecrets: - name: default-secret volumes: - name: java-oom-pv persistentVolumeClaim: claimName: jvm-sfs-pvc #使用SFS的PVC,名称为jvm-sfs-pvc EOF
- 等待一会后,容器会发生OOM自动重启。
# kubectl -n default get pod NAME READY STATUS RESTARTS AGE java-application-84dc6f897f-hc9q7 1/1 Running 1 (31s ago) 97s
- 获取Java程序因为OOM产生的文件。
- 前往CCE控制台,单击集群名称进入集群,在左侧导航栏中选择“存储”,找到jvm-sfs-pvc的存储卷声明,单击关联的存储卷PV名称。
- 自动跳转到PVC对应的存储卷,单击关联的卷名称。
- 自动跳转到弹性文件服务控制台,复制挂载命令。
- 登录一台集群节点,新建挂载点并运行挂载命令,挂载此通用文件存储卷。
mkdir /test-jvm mount -t nfs -o vers=3,timeo=600,noresvport,nolock,proto=tcp ***.com:/pvc-4ea9137e-4101-4610-a4d2-9f8bb37043a1 /test-jvm
- 查看挂载的文件系统里的文件,目录中存在转储文件java_pid1.hprof。如果您需要定位到程序发生OOM的代码行数,可以将java_pid1.hprof下载到本地,通过MAT(Eclipse Memory Analyzer Tools)进一步分析JVM堆栈信息。