Docker容器只有JRE没有JDK使用Jattach导出内存快照

Docker容器只有JRE没有JDK使用Jattach导出内存快照

缘起

目前生产环境(k8s部署的)发现某个服务被重启了,当前监控只有普罗米修斯,可以看到当时的内存和CPU都很高。服务接入了阿里的监控工具ARMS,但是没法导出当时的内存快照,ARMS虽然提供了手动导出的功能,但是人很难确定哪个时间点的内存快照是最合适的。虽然服务重启了,但是没有OOM,所以OOM时导出内存快照开关虽然打开了,但是没有导出。服务重启的原因是k8s的healthcheck超时导致监控认为服务挂了,就把它重启了,但是当时只是响应慢,并不是真的挂了。生产上目前只有JRE,没有JDK,所以没办法像网上大多数人讲的那样,直接使用jstack和jmp等命令导出

Jattach

在网上搜索的时候发现了两个思路

  1. agentlib 启动时使用java -agentlib:heap=dump -jar xxx.jar 这个后来发现也需要jdk GG了
  2. jattach 实现了HotSpot Attach API,可以在JRE中直接执行 参考github https://github.com/apangin/jattach

导出内存快照

a. 下载合适的jattach工具,地址:https://github.com/apangin/jattach/releases
我这边用的debian镜像,所以将Docker容器只有JRE没有JDK使用Jattach导出内存快照_第1张图片
下载下来,放到和dockerfile同一个文件夹下(我这边dockerfile不是放在项目里面的,是单独放在某个文件夹,运维给挂载进去的)
b. 将a中的jattach工具放入镜像的/usr/bin 并且赋执行权限

COPY jattach /usr/bin
RUN chmod +x /usr/bin/jattach

c. build镜像然后发布后,进入容器内执行

jattach 1 dumpheap /opt/app/dumpheap.hprof
jattach 1 threaddump > /opt/app/threaddump.hprof

这样就把内存快照和当时的CPU信息导出了,让运维把/opt/app/这个目录挂载到一个外部磁盘上,就可以拿到导出的信息了

你可能感兴趣的:(JAVA,linux,docker,java,linux)