歡迎光臨
每天分享高質量文章

分散式鏈路追蹤 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

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 整體類結構。如下圖所示 :

  • 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】

贊(0)

分享創造快樂