现状

加参数 -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(){
fmt.Println("init....")
flag.StringVar(&env, "env", "test", "test") //用于区分环境
flag.StringVar(&ddtoken, "ddtoken", "", "ddtoken") //用于报警用的 钉钉机器人TOKEN
flag.StringVar(&dumpFile, "dfile", "", "dfile") // dump文件的地址
flag.StringVar(&pod, "pod", "", "pod") //k8s中的pod 只是记录一下 方便排查
}

main函数逻辑


func main() {
fmt.Println("start invoke dump...")
flag.Parse() //解析输入参数
fmt.Printf("dumpFile %s ,env %s token %s\n",dumpFile,env,ddtoken)
exist, err := FileExists(dumpFile) //验证dump文件是否存在 只有存在的时候才去处理收集dump文件逻辑
if err != nil {
fmt.Printf("验证文件是否存在发生错误![%v]\n", err)
return
}
if exist {
//https://help.aliyun.com/document_detail/88604.html
var url=uploadOSS(dumpFile) //上传阿里oss
fmt.Printf("OSS上传完成 %s\n", url)
if enabledd{
//钉钉群机器人发送工具 https://github.com/braumye/grobot
notifyDD(url) //通知钉钉群机器人
}
}else{
fmt.Printf("dump文件不存在 %s\n",dumpFile)
}
}

构建可执行文件


set GOOS=linux
go build -ldflags "-w -s"

测试 验证go脚本是否正确

  echo "ffff">/opt/ttt.dump
./jvmdump -env test -dfile /opt/ttt.dump

如果能成功上传 就可以集成到jvm上跑了,不能成功上传的话 就需要调一下go了。

另外分享一个-XX:OnOutOfMemoryError=./dumpError.sh 参考。

有这个shell的原因是因为 由于jvmOnOutOfMemoryError目前没有找到可以传递脚本参数的方法。 所有不能调用./jvmdump文件 故包装一下,把参数都封装在dempError.sh中 ,把所有生成的dump文件 后缀命名都设置为.dump,主要是为了方便查找。放在一个独立的目录也是可以的。

dumpError.sh

#!/bin/bash

#循环目录
traverse_dir()
{
filepath=$1 for file in `ls -a $filepath`
do
if [ -d ${filepath}/$file ]
then
if [[ $file != '.' && $file != '..' ]]
then
#递归
traverse_dir ${filepath}/$file
fi
else
#调用查找指定后缀文件
check_suffix ${filepath}/$file
fi
done
#看需要 可以kill掉进程,避免jvm没有完全崩溃 k8s不会重启pod的情况 造成应用假死问题。
} #查找指定后缀的文件 这里在k8s环境里一般只会有一个dump文件,如果可能存在多个的dump文件文件的情况 可能需要变更一下逻辑
check_suffix()
{
file=$1 #如果找到dump就调用go写的jvmdump脚本
if [ "${file##*.}"x = "dump"x ];then
lib/jvmdump -e test -dfile $file -pod $HOSTNAME -ddtoken xxx
fi
}
traverse_dir /opt/logs

完整代码参考

https://github.com/peachyy/jvmdump2k8s.git

在k8s中收集jvm异常dump文件到OSS的更多相关文章

  1. 获取JVM的dump文件

    获取JVM的dump文件的两种方式 1. JVM启动时增加两个参数: #出现 OOME 时生成堆 dump: -XX:+HeapDumpOnOutOfMemoryError #生成堆文件地址: -XX ...

  2. JVM调优 dump文件怎么生成和分析

    1.获取JVM的dump文件的两种方式 1. JVM启动时增加两个参数: #出现 OOME 时生成堆 dump: -XX:+HeapDumpOnOutOfMemoryError #生成堆文件地址: - ...

  3. Java内存泄漏分析系列之六:JVM Heap Dump(堆转储文件)的生成和MAT的使用

    原文地址:http://www.javatang.com JVM Heap Dump(堆转储文件)的生成 正如Thread Dump文件记录了当时JVM中线程运行的情况一样,Heap Dump记录了J ...

  4. C# 异常内存信息导出Dump文件

    背景:很多情况下程序崩溃我们只能看到程序抛出来的异常信息,但是有时候异常信息不清不楚我们处理异常还是一头雾水,这种情况下我们就很希望能有种办法获取程序运行时的内存进行调试,查看其中的变量.参数.方法执 ...

  5. jvm内存快照dump文件太大,怎么分析

    1.场景 通常,使用eclipse的mat图形化工具打开dump的时候都会内存溢出. 对于比较小的dump,eclipse可以打开,但一旦dump文件太大,eclipse就有点束手无策. 这时候怎么办 ...

  6. WinDbg抓取程序报错dump文件的方法

    程序崩溃的两种主要现象: a. 程序在运行中的时候,突然弹出错误窗口,然后点错误窗口的确定时,程序直接关闭 例如: “应用程序错误” “C++错误之类的窗口” “程序无响应” “假死”等 此种崩溃特点 ...

  7. K8S学习笔记之k8s日志收集实战

    0x00 简介 本文主要介绍在k8s中收集应用的日志方案,应用运行中日志,一般情况下都需要收集存储到一个集中的日志管理系统中,可以方便对日志进行分析统计,监控,甚至用于机器学习,智能分析应用系统问题, ...

  8. [Java基础] 使用JMAP dump及分析dump文件

    转载:http://blog.csdn.net/kevin_luan/article/details/8447896 http://liulinxia02.blog.163.com/blog/stat ...

  9. Dump文件的生成和使用

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/lk142500/article/detai ...

随机推荐

  1. django把变量变成字段进行搜索

    from ceshi.models import Student     #引入model中的模型 获取前端请求的参数 searchKey=request.GET.get("key" ...

  2. django安装DjangoUeditor富文本

    环境: pycharm,django1.11,python2.7 第一种:直接 pip install DjangoUeditor,直接从网上安装到pycharm 由于是直接安装,ueditor.ht ...

  3. jmeter旅程第一站:Jmeter抓包浏览器或者抓取手机app的包

    学习jmeter?从实际出发,我也是一个初学者,会优先考虑先用来做一些简单的抓包.接口测试,在实践的过程中学习jmeter用途.那么接下来,这篇文章我会以jmeter抓包开启我的jmeter旅程. 这 ...

  4. P3760-[TJOI2017]异或和【树状数组】

    正题 题目链接:https://www.luogu.com.cn/problem/P3760 题目大意 给出\(n\)个数字的一个序列\(a\),求它所有区间和的异或和 \(n\leq 10^5,\s ...

  5. 如何一次性add library to classpath

    前言:导入项目时,时常需要手动导包,提示"add library to classpath",需要一个个找报红的类 点击添加本地项目包

  6. 我决定!墙裂推荐高清无码Python电子书(文中福利)

    @ 目录 前言 视频网站学习的优点和缺点 Python基础 游戏 网站开发 前言 近几年学了Python,查阅了不少资料,如B站,慕课网,我要自学网等等,然后自己边看学书自己整理学习资料,想分享下如何 ...

  7. 15种Python片段去优化你的数据科学管道

    来源:15 Python Snippets to Optimize your Data Science Pipeline 翻译:RankFan 15种Python片段去优化你的数据科学管道 为什么片段 ...

  8. IDEA破解方法:重新刷新到30天【支持正版】

    IDEA破解方法:重新刷新到30天[支持正版] 步骤: 导入plugins.zhile.io 进入File-->Settings-->Plugins 点设置(齿轮符号)-->Mana ...

  9. 安装 webstorm--->vue

    一.先去官网下载webstorm     https://www.jetbrains.com/ 不论是Mac的还是win得都有相应的版本, 二.再去官网下载git     https://git-sc ...

  10. 前段之BOM ----DOM

    一.介绍 BOM(Browser Object Model)是指浏览器对象模型,它使 JavaScript 有能力与浏览器进行"对话". DOM (Document Object ...