分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化

本文主要基于 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 实现类简介


1. 概述

本文主要分享 SkyWalking Collector 启动初始化的过程。在分享的过程中,我们会简单介绍 Collector 每个模块及其用途。

ps :Collector 是 SkyWalking 的 Server 端。整体如下图 :

FROM https://github.com/apache/incubating-skywalking 

分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化_第1张图片

2. CollectorBootStartUp

org.skywalking.apm.collector.boot.CollectorBootStartUp ,在 apm-sniffer/apm-agentMaven 模块项目里,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 整体类结构。如下图所示 :

分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化_第2张图片

  • 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 初始化的过程,可以理解成三个阶段,如下图所示 :

    分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化_第3张图片

3.1 Module

org.skywalking.apm.collector.core.module.Module ,组件抽象类。通过实现 Module 抽象类,实现不同功能的组件。目前 Collector 的 Module 实现类如下图 :

分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化_第4张图片

#name() 抽象方法,获得组件名。目前组件名有 :

分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化_第5张图片

#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 实现类如下图 :

分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化_第6张图片

#name() 抽象方法,获得组件服务提供者名。目前组件服务提供者名有 :

分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化_第7张图片

#module() 抽象方法,获得 ModuleProvider 对应的 Module 。注意,ModuleProvider 的名字可以重复,例如上图的 jetty ,通过对应的 Module 来区分。

#requiredModules() 抽象方法,获得 ModuleProvider 依赖的 Module 名字数组。

---------- Service 相关方法 Begin ----------

#registerServiceImplementation(Class, 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」 详细解析。

3.3 Service

org.skywalking.apm.collector.core.module.Service ,服务接口。通过实现 Service 接口,实现不同功能的服务。目前 Collector 的 Service 实现类如下图 :

分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化_第8张图片

这里有一点要注意下,实际上 Module 是与 Service "直接" 一对多的关系。中间 有一层 ModuleProvider 存在的原因是,相同 Module 可以有多种 ModuleProvider 实现,而 ModuleProvider 提供提供相同功能的 Service ,但是实现不同。

以 apm-collector-storage 举例子,如下图所示 :

分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化_第9张图片

  • StorageModuleEsProvider / StorageModuleH2Provider 分别基于 ES / H2 实现,其提供存储相同数据的不同实现。例如 :

    分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化_第10张图片

一般 collector-xxx-define 的 service 包下,会定义当前模块提供的 Service 接口,如下图所示 :

分布式链路追踪 SkyWalking 源码分析 —— Collector 初始化_第11张图片

这也是为什么有 Module#services() 和 #requiredCheck(Class[]) 这样的方法涉及的原因。

另外,如下是 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}.

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】

 

在此我向大家推荐一个架构学习交流群。交流学习群号:993070439 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系,还能领取免费的学习资源。

你可能感兴趣的:(Java)