本文主要基於 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
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)
方法,獲得 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
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】