SkyWalking
2025-09-16 11:18:09 0 举报
AI智能生成
SkyWalking 链路监控源码分析
作者其他创作
大纲/内容
SkyWalkingAgent.premain()
Agent 原理
Agent 原理
启动方式
静态启动: 使用 -javaagent 参数
入口方法 premain()
在类加载时可以对字节码做任意修改,只要最后的结果符合字节码规范
SkyWalking 只支持这种方式启动 Agent
典型应用:APM 监控
动态附加:使用 Attach API
入口方法 agentmain()
类已经完成加载并使用,这时候只能对目标类的字节码做有限修改
不能增减父类
不能增加接口
不能更改 field
典型应用:系统诊断 Arthas,JVM-SANDBOX
启动流程
SnifferConfigInitializer.initialize()
初始化配置
初始化配置
SnifferConfigInitializer.loadConfig()
读取配置文件 /config/agent.config ConfigInitializer.initialize()
将上面读取到的配置属性赋值给 Config.Class SnifferConfigInitializer.overrideConfigBySystemProp()
使用系统环境变量覆盖, 环境变量必须以 skywalking 开头SnifferConfigInitializer.overrideConfigByAgentOptions()
使用 agent 参数覆盖,优先级最高 优先级从低到高
new PluginFinder(new PluginBootstrap().loadPlugins())
加载插件并分类
加载插件并分类
PluginBootstrap.loadPlugins()
加载所有插件 AgentClassLoader.initDefaultLoader()
初始化 AgentClassLoader
PluginResourcesResolver.getResources()
读取所有的 skywalking-plugin.def 资源文件
PluginCfg.load()
解析文件内容, 将其封装成 PluginDefine 集合
AbstractClassEnhancePluginDefine
使用 classloader 实例化插件对象
new PluginFinder()
在构造方法中对所有插件进行分类
在构造方法中对所有插件进行分类
定制 Agent
创建 ByteBuddy 实例
指定需要忽略增强的类
BootstrapInstrumentBoost.inject()
把一些必要的工具类注册到 Bootstrap ClassLoader 中
把一些必要的工具类注册到 Bootstrap ClassLoader 中
BootstrapInstrumentBoost.prepareJREInstrumentation()
把 jdk 核心类库的动态生成的代理模板放到 classesTypeMap 中
把 jdk 核心类库的动态生成的代理模板放到 classesTypeMap 中
把 skywalking 的一些核心工具类加载到 classesTypeMap
把 ByteBuddy 的一些核心工具类加载到 classesTypeMap
把 classesTypeMap 中定义的一些字节码加载到 BootstrapCL 中
定制 agentBuilder
type(pluginFinder.buildMatch())
指定要拦截的类, 这里构造一个巨大的插件查询条件
指定要拦截的类, 这里构造一个巨大的插件查询条件
transform(new Transformer(pluginFinder))
指定 Transformer 插桩增强类
指定 Transformer 插桩增强类
with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
指定字节码增强的模式,使用 RETRANSFORMATION
指定字节码增强的模式,使用 RETRANSFORMATION
with(new Listener())
对 Transformer 后的监听, 输出日志
对 Transformer 后的监听, 输出日志
installOn(instrumentation)
将 Agent 安装到 instrumentation
将 Agent 安装到 instrumentation
ServiceManager.INSTANCE.boot()
加载并启动服务
加载并启动服务
ServiceManager.loadAllServices()
加载所有服务实例,需要实现 BootService 接口
加载所有服务实例,需要实现 BootService 接口
ServiceManager.load()
使用 serviceloader 加载所有的 BootService SPI 实例
使用 serviceloader 加载所有的 BootService SPI 实例
@DefaultImplementor
默认实现
默认实现
@OverrideImplementor
覆盖实现
覆盖实现
ServiceManager.prepare()
分别调用 prepare() 方法
分别调用 prepare() 方法
ServiceManager.startup()
分别调用 startup() 方法
分别调用 startup() 方法
ServiceManager.onComplete()
分别调用 onComplete() 方法
分别调用 onComplete() 方法
注册 JVM ShutdownHook
ServiceManager.shutdown()
分别调用 shutdown() 方法
分别调用 shutdown() 方法
Transformer.transform()
Plugin 原理
Plugin 原理
PluginFinder.find()
查找所有对指定类型能够生效的插件
查找所有对指定类型能够生效的插件
nameMatchDefine
直接匹配,按照类名匹配
直接匹配,按照类名匹配
signatureMatchDefine
间接匹配, 需要调用 IndirectMatch.isMatch() 方法判断
间接匹配, 需要调用 IndirectMatch.isMatch() 方法判断
AbstractClassEnhancePluginDefine.define()
调用插件的拦截方法, 获取拦截后的字节码
调用插件的拦截方法, 获取拦截后的字节码
witnessClasses()
所有插件都可以定义一些 witnessClasses
所有插件都可以定义一些 witnessClasses
ClassEnhancePluginDefine.enhance()
增强目标类
增强目标类
ClassEnhancePluginDefine.enhanceClass()
增强静态方法
增强静态方法
getStaticMethodsInterceptPoints()
获取生效插件定义的静态方法拦截点
获取生效插件定义的静态方法拦截点
静态方法拦截点处理
重写入参
是 JDK 类库
不是 JDK 类库
不重写入参
是 JDK 类库
BootstrapInstrumentBoost.forInternalDelegateClass()
直接构造出之前放入到 BootstrapCL 中的 xx_internal 对象,也就是之前定义的模板对象
直接构造出之前放入到 BootstrapCL 中的 xx_internal 对象,也就是之前定义的模板对象
InstanceMethodInterTemplate
假设以这个为例
假设以这个为例
InstanceMethodInterTemplate.intercept()
拦截处理
拦截处理
InstanceMethodInterTemplate.prepare()
JDK 的核心类库会首先调用 prepare() 方法
JDK 的核心类库会首先调用 prepare() 方法
其它处理逻辑同静态方法
不是 JDK 类库
getMethodsInterceptor()
获取自定义的方法拦截点, 它是一个字符串(类限定名), 后面会反射创建实例对象
获取自定义的方法拦截点, 它是一个字符串(类限定名), 后面会反射创建实例对象
StaticMethodsInter
使用 ByteBuddy api 将真正的代理逻辑交给这个类
使用 ByteBuddy api 将真正的代理逻辑交给这个类
StaticMethodsInter.intercept()
拦截处理
拦截处理
InterceptorInstanceLoader.load()
根据传入的静态方法拦截器类限定名反射创建实例对象
根据传入的静态方法拦截器类限定名反射创建实例对象
interceptor.beforeMethod()
调用拦截器的 beforeMethod() 方法
调用拦截器的 beforeMethod() 方法
zuper.call()
调用原方法
调用原方法
如果执行时抛出异常
调用拦截器的 handleMethodException() 异常方法
调用拦截器的 handleMethodException() 异常方法
interceptor.afterMethod()
在 finally 中调用拦截器的 afterMethod() 方法
在 finally 中调用拦截器的 afterMethod() 方法
集合,循环处理
ClassEnhancePluginDefine.enhanceInstance()
增强构造方法和实例方法
增强构造方法和实例方法
getConstructorsInterceptPoints()
获取生效插件定义的构造方法拦截点
获取生效插件定义的构造方法拦截点
getInstanceMethodsInterceptPoints()
获取生效插件定义的实例方法拦截点
获取生效插件定义的实例方法拦截点
判断当前类是否已经被增强过了, 因为不能重复定义字段, 所以这里需要判断一下
未增强过就给这个类定义一个字段 _$EnhancedClassField_ws 同时实现 EnhancedInstance 接口
最后通过 context.extendObjectCompleted() 标记已经完成了增强
未增强过就给这个类定义一个字段 _$EnhancedClassField_ws 同时实现 EnhancedInstance 接口
最后通过 context.extendObjectCompleted() 标记已经完成了增强
构造方法拦截点处理
是 JDK 类库
不是 JDK 类库
ConstructorInter
使用 ByteBuddy api 将真正的代理逻辑交给这个类
使用 ByteBuddy api 将真正的代理逻辑交给这个类
ConstructorInter.<init>
在构造函数中初始化
在构造函数中初始化
InterceptorInstanceLoader.load()
根据传入的构造方法拦截器类限定名反射创建实例对象
根据传入的构造方法拦截器类限定名反射创建实例对象
ConstructorInter.intercept()
拦截处理
拦截处理
onConstruct()
当原生的构造方法执行完成后, 会调用 onConstruct() 方法
当原生的构造方法执行完成后, 会调用 onConstruct() 方法
实例方法拦截点处理
判断是不是声明式拦截点,有些没有办法直接定位到具体的方法名称
类似标注了 @RestController 都需要拦截, 但并不清楚具体的方法名称
类似标注了 @RestController 都需要拦截, 但并不清楚具体的方法名称
不重写入参
是 JDK 类库
不是 JDK 类库
InstMethodsInter
使用 ByteBuddy api 将真正的代理逻辑交给这个类
使用 ByteBuddy api 将真正的代理逻辑交给这个类
分析原理基本同静态方法
重写入参
是 JDK 类库
不是 JDK 类库
集合,循环处理
集合,循环处理
EnhanceContext.initializationStageCompleted()
标记这个类已经增强过, 防止重复增强(比如重复定义字段)
标记这个类已经增强过, 防止重复增强(比如重复定义字段)
BootService 原理
GRPCChannelManager
负责 Agent 到 OAP 的 GRPC 网络连接
负责 Agent 到 OAP 的 GRPC 网络连接
ServiceAndEndpointRegisterClient
负责上报服务信息和心跳
负责上报服务信息和心跳
CommandService
负责接收 OAP 的响应
负责接收 OAP 的响应
SamplingService
采样是否需要上报到 OAP
采样是否需要上报到 OAP
JVMService
JVM 信息上报
JVM 信息上报
TraceSegmentServiceClient
收集上报 trace 信息
收集上报 trace 信息
0 条评论
下一页