自我表扬:《Dubbo 实现原理与源码解析 —— 精品合集》
表扬自己:《D数据库实体设计合集》

摘要: 原创出处 http://www.iocoder.cn/SkyWalking/agent-init/ 「芋道源码」欢迎转载,保留摘要,谢谢!

本文主要基于 SkyWalking 3.2.6 正式版


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

1. 概述

本文主要分享 SkyWalking Agent 启动初始化的过程

SkyWalking Agent 基于 JavaAgent 机制,实现应用透明接入 SkyWalking 。关于 JavaAgent 机制,笔者推荐如下两篇文章 :

友情提示 :建议自己手撸一个简单的 JavaAgent ,更容易理解 SkyWalking Agent 。

笔者练手的 JavaAgent 项目地址 :https://github.com/YunaiV/learning/tree/master/javaagent01

2. SkyWalkingAgent

org.skywalking.apm.agent.SkyWalkingAgent ,在 apm-sniffer/apm-agent Maven 模块项目里,SkyWalking Agent 启动入口。为什么说它是启动入口呢?在 apm-sniffer/apm-agentpom.xml 文件的【第 73 行】,我们可以看到 SkyWalkingAgent 被配置成 JavaAgent 的 PremainClass

#premain(...) 方法,代码如下 :

  • 第 58 行 :调用 SnifferConfigInitializer#initialize() 方法,初始化 Agent 配置。
  • 第 61 行 :调用 PluginBootstrap#loadPlugins() 方法,加载 Agent 插件们。而后,创建 PluginFinder 。
  • 第 64 行 :调用 ServiceManager#boot() 方法,初始化 Agent 服务管理。在这过程中,Agent 服务们会被初始化。
  • 第 79 至 133 行 :基于 byte-buddy ,初始化 Instrumentation 的 java.lang.instrument.ClassFileTransformer

3. SnifferConfigInitializer

org.skywalking.apm.agent.core.conf.SnifferConfigInitializer ,Agent 配置初始化器。

在看具体代码实现之前,我们先看下 org.skywalking.apm.agent.core.conf 包的大体结构 :

配置类有 Config 和 RemoteDownstreamConfig 两种。从命名上可以看出 :

  • Config 为 Agent 本地配置类,使用 SnifferConfigInitializer 进行初始化。
  • RemoteDownstreamConfig 为 Agent 远程配置类,从 Collector Server 读取。

#initialize() 方法,初始化 Agent 本地配置,代码如下 :

  • 第 59 至 67 行 :从配置文件( agent.config ) 加载配置。配置文件所在固定路径为 ${AGENT_PACKAGE_PATH}/config/agent.config ,其中 ${AGENT_PACKAGE_PATH} 通过 org.skywalking.apm.agent.core.boot.AgentPackagePath 初始化。Agent 整理目录如下图 :
  • 第 70 至 74 行 :从环境变量覆盖配置。环境变量 Key 需以 "skywalking." 开头。例如,Config.Agent.APPLICATION_CODEagent.configagent.application_code ,环境变量为 skywalking.agent.application_code 。另外,环境变量包括 JVM 进程的和系统的。
  • 第 77 至 82 行 :校验配置是否正确加载。

3.1 Config

org.skywalking.apm.agent.core.conf.Config ,Agent 本地配置类。

打开 Config ,我们会看到拆分了 Agent / Collector / Jvm / Buffer / Dictionary / Logging / Plugin 七个小类。如下图 :

本文暂不对配置项详细解析,胖友可以看下每个属性的英文注释。

3.2 RemoteDownstreamConfig

org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig ,Agent 远程配置类。

打开 RemoteDownstreamConfig ,我们会看到拆分了 Agent / Collector 两小类。如下图 :

本文暂不对配置项详细解析,胖友可以看下每个属性的英文注释。

4. Plugin

SkyWalking Agent 提供了多种插件,实现不同框架的透明接入 SkyWalking 。在 《官方文档 —— supported list》 里,有目前的插件列表。

另外,在 apm-sniffer/apm-sdk-plugin 目录下,有插件的实现代码 :

本小节会分享的较为简单,在 《SkyWalking 源码分析 —— Agent 插件体系》 详细解析。

4.1 PluginBootstrap

org.skywalking.apm.agent.core.plugin.PluginBootstrap ,插件引导程序类,创建需要加载的插件对象数组。

#loadPlugins() 方法,代码如下 :

4.2 PluginFinder

org.skywalking.apm.agent.core.plugin.PluginFinder ,插件发现者。其提供 #find(...) 方法,获得类增强插件定义( org.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine )对象。

PluginFinder 构造方法,代码如下 :

  • 第 57 至 77 行 :循环 AbstractClassEnhancePluginDefine 对象数组,添加到 nameMatchDefine / signatureMatchDefine 属性,方便 #find(...) 方法查找 AbstractClassEnhancePluginDefine 对象。
    • 第 65 至 72 行 :处理 NameMatch 为匹配的 AbstractClassEnhancePluginDefine 对象,添加到 nameMatchDefine 属性。
    • 第 74 至 76 行 :处理 NameMatch 为匹配的 AbstractClassEnhancePluginDefine 对象,添加到 signatureMatchDefine 属性。

5. ServiceManager

org.skywalking.apm.agent.core.boot.ServiceManagerBootService 管理器。负责管理、初始化 BootService 实例们。

#boot() 方法,代码如下 :

5.1 BootService

org.skywalking.apm.agent.core.boot.BootService ,Agent 启动服务接口,定义了 #beforeBoot() / #boot() / #afterBoot() / #shutdown() 接口方法。

BootService 目前有七个实现类,在后续的文章,我们会解析相关实现。

666. 彩蛋

知识星球

每次写初始化相关的文章,写少了,怕太水;写多了,又怕太复杂。

嗯,送一发妹子。

胖友,分享个朋友圈可好?

文章目录
  1. 1. 1. 概述
  2. 2. 2. SkyWalkingAgent
  3. 3. 3. SnifferConfigInitializer
    1. 3.1. 3.1 Config
    2. 3.2. 3.2 RemoteDownstreamConfig
  4. 4. 4. Plugin
    1. 4.1. 4.1 PluginBootstrap
    2. 4.2. 4.2 PluginFinder
  5. 5. 5. ServiceManager
    1. 5.1. 5.1 BootService
  6. 6. 666. 彩蛋