本文共 1468 字,大约阅读时间需要 4 分钟。
在使用 Apache SkyWalking 的线程池插件时,可能会遇到 traceId 为空的问题。以下是详细的排查过程和解决方案。
最近公司在进行全链路追踪,选择 Apache SkyWalking 作为核心实现工具。对于异步链路的 trace 覆盖,已经有了线程池插件(apm-jdk-threadpool-plugin.jar)。在应用中使用该插件时,发现线程池提交任务时 traceId 为空。经过初步排查,发现问题与类加载阶段的插件激活逻辑有关。
插件配置问题
tomcat-7.x-8.x-plugin 和 apm-jdk-threadpool-plugin,发现线程池插件生效。类加载器实例化问题
AgentClassLoader 实例化了两次,导致扫描 jar 包的日志多次输出。AgentClassLoader 的构造器,发现第一次在 premain 方法启动时实例化,第二次在 main 方法启动时加载插件时再次实例化。日志扫描与依赖问题
InterceptorInstanceLoader 中发现,扫描 jar 包的逻辑存在缓存问题,可能导致多次扫描。ThreadPoolExecutor 类在日志组件 FileWriter 中被多次依赖,导致增强失败。类加载顺序分析
TraceClassLoading,观察到 ThreadPoolExecutor 类在 transform 阶段被依赖。ThreadPoolExecutor 在 FileWriter 中的初始化触发了 transform,而 transform 阶段依赖已加载的 ThreadPoolExecutor 类,导致循环依赖问题。解决方案
AgentClassLoader 为单例模式,避免重复实例化和多次扫描 jar 包。FileWriter 中注释掉线程池的初始化代码,改为其他实现方式,避免对 ThreadPoolExecutor 的依赖。线程池插件为什么会失败?
重复实例化的影响
AgentClassLoader 实例化多次,导致日志多次输出,可能引发多次扫描 jar 包。ThreadPoolExecutor 类的多次依赖,触发 transform 逻辑。JVM 类加载机制的限制
ThreadPoolExecutor 的依赖,导致增强失败。确保插件单例
AgentClassLoader 为单例模式,避免重复实例化和多次扫描 jar 包。优化日志组件
FileWriter 中注释掉线程池的初始化代码,改为其他实现方式,避免对 ThreadPoolExecutor 的依赖。简化插件测试
线程池插件的增强失败问题主要源于类加载顺序和重复实例化。通过确保插件单例和优化日志组件,可以有效解决问题。
转载地址:http://isqfk.baihongyu.com/