本文主要基于 SkyWalking 3.2.6 正式版
1. 概述
- 2. CollectorBootStartUp
- 2. ApplicationConfigLoader
- 3. ModuleManager
- 3.1 Module
- 3.2 ModuleProvider
- 3.3 Service
- 3.4 BootstrapFlow
4. Module 实现类简介
RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
您对于源码的疑问每条留言都将得到认真回复甚至不知道如何读源码也可以请教噢
新的源码解析文章实时收到通知每周更新一篇左右
认真的源码交流微信群
1. 概述
本文主要分享 SkyWalking Collector 启动初始化的过程在分享的过程中, 我们会简单介绍 Collector 每个模块及其用途
ps :Collector 是 SkyWalking 的 Server 端整体如下图 :
FROM https://github.com/apache/incubating-skywalking
- 2. CollectorBootStartUp
- org.skywalking.apm.collector.boot.CollectorBootStartUp
, 在
apm-sniffer/apm-agent
Maven 模块项目里, SkyWalking Collector 启动入口
#main(args) 方法, 启动 Collector , 代码如下 :
第 45 行 : 调用
ApplicationConfiguration#load()
方法, 加载 Collector 配置
第 47 行 : 调用
ModuleManager#init(...)
方法, 初始化 Collector 组件们
第 60 行 : 调用 Thread#sleep(60000) 方法, 等待 Collector 内嵌的 Jetty Server 启动完成
- 2. ApplicationConfigLoader
- org.skywalking.apm.collector.boot.config.ApplicationConfigLoader
, 实现
org.skywalking.apm.collector.boot.config.ConfigLoader
接口, Collector 配置(
org.skywalking.apm.collector.core.module.ApplicationConfiguration
)加载器
在看具体代码实现之前, 我们先了解下 ApplicationConfiguration 整体类结构如下图所示 :
Collector 使用组件管理器( ModuleManager ), 管理多个组件( Module )
一个组件有多种组件服务提供者( ModuleProvider ), 同时一个组件只允许使用一个组件服务提供者这块下面会有代码解析说明
Collector 使用一个应用配置类( ApplicationConfiguration )
一个应用配置类包含多个组件配置类 ( ModuleConfiguration ) 每个组件对应一个组件配置类
一个组件配置类包含多个组件服务提供者配置 ( ProviderConfiguration ) 每个组件服务提供者对应一个组件配置类注意: 因为一个组件只允许同时使用一个组件服务提供者, 所以一个组件配置类只设置一个组件服务提供者配置
整个配置文件, 对应应用配置类绿框部分, 对应一个组件配置类红框部分, 对应一个组件服务提供者配置类
下面, 我们来看看
ApplicationConfigLoader#load()
方法, 代码如下 :
第 47 行 : 调用 #loadConfig() 方法, 从 apm-collector-core 的 application.yml 加载自定义配置
第 49 行 : 调用
#loadDefaultConfig()
方法, 从 apm-collector-core 的
application-default.yml
加载默认配置
两个方法逻辑基本一致, 已经添加代码注释, 胖友自己阅读理解
- 3. ModuleManager
- org.skywalking.apm.collector.core.module.ModuleManager
, 组件管理器, 负责组件的管理与初始化
#init() 方法, 初始化组件们, 代码如下 :
第 51 至 53 行 : 调用
java.util.ServiceLoader#load(Module.class)
方法, 加载所有 Module 实现类的实例数组 ServiceManager 基于 SPI (Service Provider Interface) 机制, 在每个
apm-collector-xxx-define
项目的
/resources/META-INF.services/org.skywalking.apm.collector.core.module.Module
文件里, 定义了该项目 Module 的实现类如果胖友对 SPI 机制不熟悉, 可以看下如下文章 :
SPI 和 ServiceLoader
跟我学 Dubbo 系列之 Java SPI 机制简介
第 55 至 75 行 : 遍历所有 Module 实现类的实例数组, 创建在配置中的 Module 实现类的实例, 并执行 Module 准备阶段的逻辑, 后添加到加载的组件实例的映射( loadedModules )
第 59 至 67 行 : 创建 Module 对象
第 69 行 : 调用 Module#prepare(...) 方法, 执行 Module 准备阶段的逻辑在改方法内部, 会创建 Module 对应的 ModuleProvider 在 3.1 Module 详细解析
第 71 行 : 添加到 loadedModules
第 77 至 80 行 : 校验在配置中的 Module 实现类的实例都创建了, 否则抛出异常
第 84 行 : 调用
BootstrapFlow#start(...)
方法, 执行 Module 启动逻辑 3.4 BootstrapFlow 详细解析
第 86 行 : 调用
BootstrapFlow#notifyAfterCompleted()
方法, 执行 Module 启动完成, 通知 ModuleProvider 3.4 BootstrapFlow 详细解析
总的来说, Module 初始化的过程, 可以理解成三个阶段, 如下图所示 :
- 3.1 Module
- org.skywalking.apm.collector.core.module.Module
, 组件抽象类通过实现 Module 抽象类, 实现不同功能的组件目前 Collector 的 Module 实现类如下图 :
- #name() 抽象方法, 获得组件名目前组件名有 :
- #providers() 方法, 获得 ModuleProvider 数组实际上, 一个 Module 同时只能有一个 ModuleProvider , 参见 #provider() 方法
- #services() 抽象方法, 获得 Service 类数组具体 Service 对象, 在 ModuleProvider 对象里获取, 参见
- #getService(serviceType)
方法
#prepare(...) 方法, 执行 Module 准备阶段的逻辑, 代码如下 :
第 69 行 : 调用
java.util.ServiceLoader#load(ModuleProvider.class)
方法, 加载所有 ModuleProvider 实现类的实例数组 ServiceManager 基于 SPI (Service Provider Interface) 机制, 在每个
apm-collector-xxx-yyy-provider
项目的
/resources/META-INF.services/org.skywalking.apm.collector.core.module.ModuleProvider
文件里, 定义了该项目 ModuleProvider 的实现类
第 72 至 93 行 : 遍历所有 ModuleProvider 实现类的实例数组, 创建在配置中的 ModuleProvider 实现类的实例, 后添加到加载的组件服务提供者实例的映射( loadedProviders )
第 95 至 98 行 : 校验有 ModuleProvider 初始化, 否则抛出异常
第 100 至 104 行 : 调用
ModuleProvider#prepare(...)
方法, 执行 ModuleProvider 准备阶段的逻辑在改方法内部, 会创建 ModuleProvider 对应的 Service 在 3.2 ModuleProvider 详细解析
- 3.2 ModuleProvider
- org.skywalking.apm.collector.core.module.ModuleProvider
, 组件服务提供者抽象类通过实现 ModuleProvider 抽象类, 实现不同功能的组件服务提供者目前 Collector 的 ModuleProvider 实现类如下图 :
- #name() 抽象方法, 获得组件服务提供者名目前组件服务提供者名有 :
- #module() 抽象方法, 获得 ModuleProvider 对应的 Module 类注意, ModuleProvider 的名字可以重复, 例如上图的 jetty , 通过对应的 Module 类来区分
- #requiredModules() 抽象方法, 获得 ModuleProvider 依赖的 Module 名字数组
---------- Service 相关方法 Begin ----------
#registerServiceImplementation(Class<? extends Service>, Service)
方法, 注册 Service 对象一个 ModuleProvider 可以有 0 到 N 个 Service 对象
#getService(Class<T>)
方法, 获得 Service 对象
#requiredCheck(...) 方法, 校验 ModuleProvider 包含的 Service 们都创建成功
方法参数, 从 Module#services() 方法获得
该方法会被
BootstrapFlow#start()
方法调用, 在 3.4 BootstrapFlow 详细解析
---------- Service 相关方法 End ----------
#prepare(Properties)
抽象方法, 执行 ModuleProvider 准备阶段的逻辑: Service 的创建, 私有变量的创建等等例如,
- StorageModuleH2Provider#prepare(Properties)
- #start(Properties) 抽象方法, 执行 ModuleProvider 启动阶段的逻辑: 私有变量的初始化等等例如,
- StorageModuleH2Provider#start(Properties)
该方法会被
BootstrapFlow#start()
方法调用, 在 3.4 BootstrapFlow 详细解析
#notifyAfterCompleted()
抽象方法, 执行 ModuleProvider 启动完成阶段的逻辑: 私有变量的初始化等等例如,
StorageModuleEsProvider#notifyAfterCompleted(Properties)
该方法会被
BootstrapFlow#notifyAfterCompleted()
方法调用, 在 3.4 BootstrapFlow 详细解析
- 3.3 Service
- org.skywalking.apm.collector.core.module.Service
, 服务接口通过实现 Service 接口, 实现不同功能的服务目前 Collector 的 Service 实现类如下图 :
这里有一点要注意下, 实际上 Module 是与 Service "直接" 一对多的关系中间 有一层 ModuleProvider 存在的原因是, 相同 Module 可以有多种 ModuleProvider 实现, 而 ModuleProvider 提供提供相同功能的 Service , 但是实现不同
以
apm-collector-storage
举例子, 如下图所示 :
StorageModuleEsProvider / StorageModuleH2Provider 分别基于 ES / H2 实现, 其提供存储相同数据的不同实现例如 :
一般
collector-xxx-define
的 service 包下, 会定义当前模块提供的 Service 接口, 如下图所示 :
这也是为什么有 Module#services() 和
#requiredCheck(Class<? extends Service>[])
这样的方法涉及的原因
另外, 如下是 Service 接口的解释:
- The <code>Service</code> implementation is a service provided by its own modules.
- And every {@link ModuleProvider} must provide all the given services of the {@link Module}.
- 3.4 BootstrapFlow
- org.skywalking.apm.collector.core.module.BootstrapFlow
, 组件启动流程
BootstrapFlow 构造方法, 调用 #makeSequence() 方法, 获得 ModuleProvider 启动顺序, 这个是该类的重点
#start() 方法, 执行 Module 启动逻辑
第 54 至 63 行 : 校验依赖 Module 已经都存在
第 67 行 : 校验 ModuleProvider 包含的 Service 们都创建成功
第 70 行 : 调用
ModuleProvider#start(...)
方法, 执行 ModuleProvider 启动阶段逻辑
#notifyAfterCompleted()
方法, 调用
ModuleProvider#notifyAfterCompleted()
方法, 执行 ModuleProvider 启动完成阶段的逻辑
4. Module 实现类简介
Naming Module :SkyWalking 源码分析 Collector Naming Server 命名服务
UI Module :
SkyWalking 源码分析 运维界面 (一) 之应用视角
SkyWalking 源码分析 运维界面 (二) 之应用实例视角
SkyWalking 源码分析 运维界面 (三) 之链路追踪视角
SkyWalking 源码分析 运维界面 (四) 之操作视角
Queue Module :SkyWalking 源码分析 Collector Queue 队列组件
Cache Module :SkyWalking 源码分析 Collector Cache 缓存组件
Cluster Module :SkyWalking 源码分析 Collector Cluster 集群管理
Component Libraries :SkyWalking 源码分析 Collector Client Component 客户端组件 SkyWalking 源码分析 Collector Server Component 服务器组件
Core :
SkyWalking 源码分析 Collector Storage 存储组件 2. apm-collector-core
SkyWalking 源码分析 Collector 初始化 3. ModuleManager
Storage Module :SkyWalking 源码分析 Collector Storage 存储组件
SkyWalking 源码分析 Collector Streaming Computing 流式处理(一)2. apm-collector-core/graph
SkyWalking 源码分析 Collector Streaming Computing 流式处理(二)2. Data
Agent Module : 参见 Agent Streaming Computing
Jetty Manager Module :SkyWalking 源码分析 Collector Jetty Server Manager
gRPC Manager Module :SkyWalking 源码分析 Collector gRPC Server Manager
Agent Streaming Computing :
SkyWalking 源码分析 Collector Streaming Computing 流式处理(一)2. apm-collector-core/graph
SkyWalking 源码分析 Collector Streaming Computing 流式处理(二)2. Data
SkyWalking 源码分析 Collector Remote 远程通信服务
SkyWalking 源码分析 Agent 收集 Trace 数据
SkyWalking 源码分析 Agent 发送 Trace 数据
SkyWalking 源码分析 Collector 接收 Trace 数据
SkyWalking 源码分析 Collector 存储 Trace 数据
- Baseline Module :TODO 4001
- Alerting Module :TODO 4001
666. 彩蛋
可能要进入特别忙碌的一段时间, 不确定 SkyWalking 文章后续的更新频率
继续加油
胖友, 分享个朋友圈可好?
来源: http://www.suo.im/33VQ6u