缘起
目前生产环境(k8s部署的)发现某个服务被重启了,当前监控只有普罗米修斯,可以看到当时的内存和CPU都很高。服务接入了阿里的监控工具ARMS,但是没法导出当时的内存快照,ARMS虽然提供了手动导出的功能,但是人很难确定哪个时间点的内存快照是最合适的。虽然服务重启了,但是没有OOM,所以OOM时导出内存快照开关虽然打开了,但是没有导出。服务重启的原因是k8s的healthcheck超时导致监控认为服务挂了,就把它重启了,但是当时只是响应慢,并不是真的挂了。生产上目前只有JRE,没有JDK,所以没办法像网上大多数人讲的那样,直接使用jstack和jmp等命令导出
Jattach
在网上搜索的时候发现了两个思路
- agentlib 启动时使用java -agentlib:heap=dump -jar xxx.jar 这个后来发现也需要jdk GG了
- jattach 实现了HotSpot Attach API,可以在JRE中直接执行 参考github https://github.com/apangin/jattach
导出内存快照
a. 下载合适的jattach工具,地址:https://github.com/apangin/jattach/releases 我这边用的debian镜像,所以将 下载下来,放到和dockerfile同一个文件夹下(我这边dockerfile不是放在项目里面的,是单独放在某个文件夹,运维给挂载进去的) b. 将a中的jattach工具放入镜像的/usr/bin
并且赋执行权限
c. build镜像然后发布后,进入容器内执行COPY jattach /usr/bin RUN chmod +x /usr/bin/jattach
这样就把内存快照和当时的CPU信息导出了,让运维把jattach 1 dumpheap /opt/app/dumpheap.hprof jattach 1 threaddump > /opt/app/threaddump.hprof
/opt/app/
这个目录挂载到一个外部磁盘上,就可以拿到导出的信息了