背景
最近公司部署的k8s java应用频繁oom,又不及时告警,导致发现不及时,而且oom之后产生的dump文件在k8s pod重启后就被清除了,不能及时拿到dump文件进行问题追踪,故此需要做一个java应用oom的时候发出告警到企业微信,并且把dump文件上传到minio文件存储系统
需求
- 要求1: docker 或者 k8s 部署的应用,在应用oom后,会发告警到企业微信,并且自动把dump文件自动上传到minio。
- 要求2:同应用同同份dump文件只会上传一次。重复上传要覆盖掉旧的dump文件,下载后需要手动删除,因为每份dump文件太大,如果不及时处理,将会造成minio磁盘爆满
实现步骤
- 容器内应用新增环境变量
JAVA_TOOL_OPTIONS
JAVA_TOOL_OPTIONS 是一个环境变量,它可以用来设置 Java 虚拟机(JVM)的默认选项和参数。当你在命令行中运行 Java 程序时,可以使用 JAVA_TOOL_OPTIONS 来指定 JVM 的各种配置。
以下为我的环境变量参数
-XX:InitialRAMPercentage=40.0 -XX:MinRAMPercentage=20.0 -XX:MaxRAMPercentage=80.0 -javaagent:/skywalking/agent/skywalking-agent.jar=agent.instance_name=k8s-prod -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/run/1.hprof -XX:+ExitOnOutOfMemoryError -XX:OnOutOfMemoryError=/opt/run/oom.sh
其中和本文相关的关键配置为以下四个配置
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/run/1.hprof
-XX:+ExitOnOutOfMemoryError
-XX:OnOutOfMemoryError=/opt/run/oom.sh
JVM相关参数解释
-
-XX:+HeapDumpOnOutOfMemoryError
: 当发生内存溢出错误(Out of Memory Error)时,将会生成一个堆转储文件(Heap Dump)。堆转储文件是一个二进制文件,记录了 JVM 堆中对象的详细信息,可以用于分析内存使用情况和调试。使用该选项启用堆转储功能。 -
-XX:HeapDumpPath=/opt/run/1.hprof
: 指定堆转储文件的保存路径和文件名。在这个示例中,堆转储文件将保存在/opt/run
目录下,并命名为1.hprof
。 -
-XX:+ExitOnOutOfMemoryError
: 当发生内存溢出错误时,JVM 将直接退出。通常情况下,JVM 在发生内存溢出错误后会尝试继续执行程序,但可能会导致未定义行为或进一步的错误。使用该选项可以使 JVM 在出现内存溢出错误时立即退出。 -
-XX:OnOutOfMemoryError=/opt/run/oom.sh
: 当发生内存溢出错误时,执行指定的 shell 脚本。在这个示例中,指定的脚本是/opt/run/oom.sh
,可以根据需要自定义这个脚本。这个特性可以让在内存溢出错误发生时执行一些自定义的操作,例如发送通知、记录日志等。
由以上的理论得知,关键点在OnOutOfMemoryError
配置,在oom的时候执行对应的脚本,以达到上传dump文件和告警的效果
告警脚本
以下为我的告警脚本
脚本里的环境变量已在应用里配置好
mc config host add minio $MINIO_URL $MINIO_USER $MINIO_PASSWORD
MINIO_DUMPS_PATH=minio/oomdumps/$SW_AGENT_NAME/1.hprof
mc cp /opt/run/1.hprof $MINIO_DUMPS_PATH
wx_alert(){
echo "发送OOM告警中!"
content="k8s部署的【${1}】发生OOM,相关dump文件已上传到minio的【'${2}'】路径下,请及时查看与删除!!"
date=$(date +%Y-%m-%d)
time=$(date "+%H:%M:%S")
content="应用OOM告警, 时间:【$date $time】, 详情:$content"
webHookUrl="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"
content='{"msgtype": "text","text": {"content": "'$content'","mentioned_mobile_list":['$3']}}'
curl -H 'Content-Type: application/json' -d "$content" $webHookUrl
echo "成功发送OOM告警!"
}
wx_alert "$APP_RUNTIMEID" "$MINIO_DUMPS_PATH"
效果
至此,需求完成
评论区