本文主要基于 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 实现类简介
本文主要分享 SkyWalking Collector 启动初始化的过程。在分享的过程中,我们会简单介绍 Collector 每个模块及其用途。
ps :Collector 是 SkyWalking 的 Server 端。整体如下图 :
FROM https://github.com/apache/incubating-skywalking
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 启动完成。
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` 加载默认配置。
两个方法逻辑基本一致,已经添加代码注释,胖友自己阅读理解。
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 初始化的过程,可以理解成三个阶段,如下图所示 :
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」 详细解析。
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
方法,获得 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」 详细解析。
org.skywalking.apm.collector.core.module.Service
,服务接口。通过实现 Service 接口,实现不同功能的服务。目前 Collector 的 Service 实现类如下图 :
这里有一点要注意下,实际上 Module 是与 Service "直接" 一对多的关系。中间 有一层 ModuleProvider 存在的原因是,相同 Module 可以有多种 ModuleProvider 实现,而 ModuleProvider 提供提供相同功能的 Service ,但是实现不同。
以 apm-collector-storage
举例子,如下图所示 :
一般 collector-xxx-define
的 service
包下,会定义当前模块提供的 Service 接口,如下图所示 :
这也是为什么有 Module#services()
和 #requiredCheck(Class extends Service>[])
这样的方法涉及的原因。
另外,如下是 Service 接口的解释:
The
Service
implementation is a service provided by its own modules.And every {@link ModuleProvider} must provide all the given services of the {@link Module}.
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 启动完成阶段的逻辑。
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】
在此我向大家推荐一个架构学习交流群。交流学习群号:993070439 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系,还能领取免费的学习资源。