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

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

分享創造快樂