现状
加参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/test.dump
可以实现在jvm
发生内存错误后 会生成dump文件 方便开发人员分析异常原因。
当运行在k8s中,如果进程发生错误 导出dump文件后 ,k8s会重启dokcer容器,上一次崩溃生成的dump文件就没有了。如果应用并没有完全崩溃 此时极其不稳定 最好也能通知到技术人员来处理。这样不方便我们排查原因 所有写了一个小工具。大概原理如下
1、 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/test.dump
当发生内存错误的时候 导出堆文件
2、 -XX:OnOutOfMemoryError=./dumpError.sh
当发生内存溢出的时候,让JVM调用一个shell脚本 这个shell脚本可以做一些资源整理操作 比如kill掉当前进程并重启
依赖上面2点jvm
特性 就能做到把dump文件收集起来 是通知技术人员也好(比如发送订单、短信报警等)、然后再把dump文件上传到OSS
或者其他的文件存储中。 需要值得注意的是-XX:OnOutOfMemoryError=xx.sh
执行的脚本不能传脚本参数,所以尽可能把参数都封装在另一个脚本中。
方案实现
基于Go
简单的写了一个上传阿里OSS的方法 这里用其他任何语言都可以的,至于用GO的原因很简单,有第三方库可以调用、运行的机器上也不用安装sdk、比较轻量。
大致逻辑如下
jvmdump.go
init获取程序的输入参数
func init(){ |
main函数逻辑
|
构建可执行文件
|
测试 验证go脚本是否正确
echo "ffff">/opt/ttt.dump |
如果能成功上传 就可以集成到jvm上跑了,不能成功上传的话 就需要调一下go了。
另外分享一个-XX:OnOutOfMemoryError=./dumpError.sh
参考。
有这个shell的原因是因为 由于jvm
中OnOutOfMemoryError
目前没有找到可以传递脚本参数的方法。 所有不能调用./jvmdump
文件 故包装一下,把参数都封装在dempError.sh中 ,把所有生成的dump文件 后缀命名都设置为.dump,主要是为了方便查找。放在一个独立的目录也是可以的。
dumpError.sh
|
完整代码参考