背景
放火平台是公司内部研发的平台:遵循混沌工程理念通过故障注入模式对系统进行演练的实施平台,提供丰富的故障场景模拟,以可视化、自动化的方式实施故障演练。
放火平台利用字节增强框架JVM-SANDBOX对 java 类型的服务进行故障注入。在业务线使用的过程中发现在放火平台对某个 java 进程故障注入后故障没有生效
在经过排查后发现主要是开源项目JVM-SANDBOX的 bug,其中涉及到 ThreadLocal,ClassLoader,Metaspace 等相关知识,具体的分析以及优化过程可以往下看。
注入流程
放火平台注入 java 故障的流程:
在注入故障时放火平台会把故障指令下发到目标机器的 chaos-agent 上,chaos-agent 利用开源项目 jvm-sandbox 对目标 jvm 进行故障注入和故障清除。
排查过程
日志表现
在注入无效后登陆目标机器上观察日志,首先发现 jvm-sandbox 在 attach 目标 jvm 时失败了
其次看到更关键的日志:Metaspace 溢出了!!!
Metaspace
Metaspace 是什么,引用官方介绍
Metaspace is a native (as in: off-heap) memory manager in the hotspot.
It is used to manage memory for class metadata. Class metadata are allocated when classes are loaded. Their lifetime is usually scoped to that of the loading classloader - when a loader gets collected, all class metadata it accumulated are released in bulk.
简单来说:Metapace 是一块非堆内存,用来存储类的元数据,当加载类的时候会在 Metaspace 中分配空间存储类的元数据,当某个 ClassLoader 关闭时会对应释放掉对类元数据的引用,当触发 GC 时这部分类元数据占用的空间即可在 Metaspace 中被回收掉。