天天看點

SkyWalking 源碼分析 —— Collector Cluster 叢集管理1. 概述2. collector-cluster-define3. collector-cluster-zookeeper-provider4. collector-cluster-standalone-provider5. collector-cluster-redis-provider

1. 概述

本文主要分享 SkyWalking Collector Cluster Module,負責叢集的管理,即 Collector 節點的注冊于發現。

友情提示:建議先閱讀 《SkyWalking 源碼分析 —— Collector 初始化》 ,以了解 Collector 元件體系。

Cluster Module 在 SkyWalking 架構圖處于如下位置( 紅框 ) :

FROM https://github.com/apache/incubating-skywalking
SkyWalking 源碼分析 —— Collector Cluster 叢集管理1. 概述2. collector-cluster-define3. collector-cluster-zookeeper-provider4. collector-cluster-standalone-provider5. collector-cluster-redis-provider

下面我們來看看整體的項目結構,如下圖所示 :

SkyWalking 源碼分析 —— Collector Cluster 叢集管理1. 概述2. collector-cluster-define3. collector-cluster-zookeeper-provider4. collector-cluster-standalone-provider5. collector-cluster-redis-provider
  • collector-cluster-define

     :定義叢集管理接口。
  • collector-cluster-standalone-provider

     :基于 H2 的 叢集管理實作。該實作是單機版,建議僅用于 SkyWalking 快速上手,生産環境不建議使用。
  • collector-cluster-redis-provider

     :基于 Redis 的叢集管理實作。目前暫未完成。
  • collector-cluster-zookeeper-provider

     :基于 Zookeeper 的叢集管理實作。生産環境推薦使用

下面,我們從接口到實作的順序進行分享。

2. collector-cluster-define

collector-cluster-define

 :定義叢集管理接口。項目結構如下 :

SkyWalking 源碼分析 —— Collector Cluster 叢集管理1. 概述2. collector-cluster-define3. collector-cluster-zookeeper-provider4. collector-cluster-standalone-provider5. collector-cluster-redis-provider
  • 互動如下圖 :
    SkyWalking 源碼分析 —— Collector Cluster 叢集管理1. 概述2. collector-cluster-define3. collector-cluster-zookeeper-provider4. collector-cluster-standalone-provider5. collector-cluster-redis-provider
  • ModuleListenerService 暴露給其他 Module 注冊監聽器 ( ClusterModuleListener ) 到 DataMonitor 。
  • ModuleRegisterService 暴露給其他 Module 注冊元件登記( ModuleRegistration ) 到 DataMonitor 。
  • 通過實作 DataMonitor 接口,基于不同的存儲器實作注冊發現。

2.1 ClusterModule

org.skywalking.apm.collector.cluster.ClusterModule

 ,實作 Module 抽象類,叢集管理 Module 。

#name()

 實作方法,傳回子產品名為 

"cluster"

 。

#services()

 實作方法,傳回 Service 類名:ModuleListenerService / ModuleRegisterService 。

2.2 ModuleRegisterService

org.skywalking.apm.collector.cluster.service.ModuleRegisterService

 ,繼承 Service 接口,子產品注冊服務接口。

#register(moduleName, providerName, registration)

 接口方法,注冊子產品注冊資訊。一般情況下,實作該接口方法,調用 

DataMonitor#register(path, registration)

 方法。

2.2.1 ModuleRegistration

org.skywalking.apm.collector.cluster.ModuleRegistration

 ,子產品注冊資訊抽象類。不同 Module 通過實作 ModuleRegistration ,将它們注冊到 ModuleRegisterService。目前子類如下 :

SkyWalking 源碼分析 —— Collector Cluster 叢集管理1. 概述2. collector-cluster-define3. collector-cluster-zookeeper-provider4. collector-cluster-standalone-provider5. collector-cluster-redis-provider

#buildValue()

 抽象方法,獲得子產品注冊資訊( Value )。

2.3 ModuleListenerService

org.skywalking.apm.collector.cluster.service.ModuleListenerService

 ,繼承 Service 接口,注冊監聽器服務接口。

#addListener(listener)

 接口方法,添加監聽器。一般情況下,實作該接口方法,調用 

DataMonitor#addListener(listener)

 方法。

2.3.1 ClusterModuleListener

org.skywalking.apm.collector.cluster.ClusterModuleListener

 ,叢集元件監聽器抽象類。目前子類如下 :

SkyWalking 源碼分析 —— Collector Cluster 叢集管理1. 概述2. collector-cluster-define3. collector-cluster-zookeeper-provider4. collector-cluster-standalone-provider5. collector-cluster-redis-provider

構造方法,建立位址數組( 

addresses

 )。該數組的讀寫方法如下:

  • #addAddress(address)

  • #removeAddress(address)

  • #getAddresses()

#path()

 抽象方法,傳回路徑。該路徑即為 ClusterModuleListener 監聽的“事件”。多個 Collector 節點的相同 Module ,通過路徑分組形成叢集。

#serverJoinNotify(serverAddress)

 / 

#serverQuitNotify(serverAddress)

 抽象方法,通知服務的加入 / 下線。目前隻有 GRPCRemoteSenderService 真正( 其它都是空方法 )實作該方法,在 《SkyWalking 源碼分析 —— Collector Remote 遠端通信服務》「3.2 GRPCRemoteSenderService」 詳細解析。

2.4 DataMonitor

org.skywalking.apm.collector.cluster.DataMonitor

 ,資料螢幕接口。通過實作 DataMonitor 接口,基于不同的存儲器實作注冊發現。目前子類如下 :

SkyWalking 源碼分析 —— Collector Cluster 叢集管理1. 概述2. collector-cluster-define3. collector-cluster-zookeeper-provider4. collector-cluster-standalone-provider5. collector-cluster-redis-provider

#register(path, registration)

 接口方法,注冊子產品注冊資訊。

#addListener(ClusterModuleListener)

 接口方法,添加監聽器。

  • #getListener(path)

     接口方法,獲得監聽指定路徑的監聽器。

#setClient(Client)

 接口方法,設定 Client 。在 

client-component

 有 ZookeeperClient / H2Client / ElasticSearchClient 等多種實作。

  • BASE_CATALOG

     屬性,基礎目錄為 

    "/skywalking"

     。例如說,在 Zookeeper 為根節點的路徑。
  • #createPath(path)

     接口方法,使用 Client 建立路徑。
  • #setData(path)

     接口方法,使用 Client 設定路徑的值。

3. collector-cluster-zookeeper-provider

collector-cluster-zookeeper-provider

 ,基于 Zookeeper 的叢集管理實作。項目結構如下 :

SkyWalking 源碼分析 —— Collector Cluster 叢集管理1. 概述2. collector-cluster-define3. collector-cluster-zookeeper-provider4. collector-cluster-standalone-provider5. collector-cluster-redis-provider

實際使用時,通過 

application.yml

 配置如下:

cluster:
  zookeeper:
    hostPort: localhost:2181
    sessionTimeout: 100000
      
  • 生産環境下,推薦 Zookeeper 配置成叢集。

3.1 ClusterModuleZookeeperProvider

org.skywalking.apm.collector.cluster.zookeeper.ClusterModuleZookeeperProvider

 ,實作 ModuleProvider 抽象類,基于 Zookeeper 的叢集管理服務提供者。

#name()

 實作方法,傳回元件服務提供者名為 

"zookeeper"

 。

module()

 實作方法,傳回元件類為 ClusterModule 。

#requiredModules()

 實作方法,傳回依賴元件為空。

#prepare(Properties)

 實作方法,執行準備階段邏輯。

  • 第 63 行 :建立 ClusterZKDataMonitor 對象。
  • 第 69 行 :建立 ZookeeperClient 對象。注意,此時并未連接配接 Zookeeper 。
  • 第 71 至 73 行 :建立 ZookeeperModuleListenerService / ZookeeperModuleRegisterService 對象,并調用 

    #registerServiceImplementation()

     父類方法,注冊到 

    services

     。

#start()

 實作方法,執行啟動階段邏輯。

  • 第 79 行 :調用 

    ZookeeperClient#initialize()

     方法,初始化 ZookeeperClient ,此時會連接配接 Zookeeper。

#notifyAfterCompleted()

 實作方法,執行啟動完成邏輯。

  • 第 88 行 :調用 

    ClusterZKDataMonitor#start()

     方法,啟動 ClusterZKDataMonitor 。在本文 「3.4 ClusterZKDataMonitor」 詳細解析。

3.2 ZookeeperModuleRegisterService

org.skywalking.apm.collector.cluster.zookeeper.service.ZookeeperModuleRegisterService

 ,基于 Zookeeper 的子產品注冊服務實作類。

#register(moduleName, providerName, registration)

 實作方法,調用 

ClusterZKDataMonitor#register(path, registration)

 方法,注冊子產品注冊資訊。

3.3 ZookeeperModuleListenerService

org.skywalking.apm.collector.cluster.zookeeper.service.ZookeeperModuleListenerService

 ,基于 Zookeeper 的注冊監聽器服務實作類。

#addListener(ClusterModuleListener)

 實作方法,調用 

ClusterZKDataMonitor#addListener(ClusterModuleListener)

 方法,注冊子產品注冊資訊。

3.4 ClusterZKDataMonitor

org.skywalking.apm.collector.cluster.zookeeper.ClusterZKDataMonitor

 ,基于 Zookeeper 的資料螢幕實作類。

在看具體代碼實作之前,我們先來看看 Zookeeper 是如何存儲資料的,如下圖所示 :

SkyWalking 源碼分析 —— Collector Cluster 叢集管理1. 概述2. collector-cluster-define3. collector-cluster-zookeeper-provider4. collector-cluster-standalone-provider5. collector-cluster-redis-provider
  • 紫色部分,通過調用 

    #createPath(path)

     方法,順着路徑,逐層建立持久節點。
  • 黃色部分,通過調用 

    #setData(path)

     方法,建立臨時節點,設定 Collector 子產品位址。若 Collector 叢集有 N 個節點,則此處會有 N 個臨時節點。
  • 打開 

    zkClient.sh

     ,我們來看一個例子 :
[zk: localhost:2181(CONNECTED) 1] ls /skywalking
[remote, ui, agent_jetty, agent_gRPC]

[zk: localhost:2181(CONNECTED) 2] ls /skywalking/ui
[jetty]

[zk: localhost:2181(CONNECTED) 3] ls /skywalking/ui/jetty
[localhost:12800]

[zk: localhost:2181(CONNECTED) 4] get /skywalking/ui/jetty/localhost:12800
/
cZxid = 0x24
ctime = Thu Dec 14 16:05:25 CST 2017
mZxid = 0x24
mtime = Thu Dec 14 16:05:25 CST 2017
pZxid = 0x24
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x16052d8b9f40006
dataLength = 1
numChildren = 0
           

#register(path, registration)

 實作方法,添加到元件注冊資訊集合( 

registrations

 )。

#start()

 方法,啟動 ClusterZKDataMonitor ,将元件注冊資訊( 

registrations

 ) 寫到 Zookeeper 中。

#addListener(listener)

 實作方法,添加到監聽器集合( 

listeners

 )。

#process(WatchedEvent)

 實作方法,處理有 Collector 節點的元件加入或下線。總體邏輯是,從 Zookeeper 擷取變更的路徑下的位址數組,和本地的位址( 

ClusterModuleListener.addresses

 )比較,處理加入或移除邏輯的位址。

  • ClusterZKDataMonitor 實作 

    org.apache.zookeeper.Watcher

     接口,是以實作該方法。
  • 該方法是 

    synchronized

     方法,以保證不會出現并發問題。

3.5 ZookeeperClient

org.skywalking.apm.collector.client.zookeeper.ZookeeperClient

 ,實作 Client 接口,Zookeeper 用戶端。

代碼比較簡單,胖友自己閱讀了解。

4. collector-cluster-standalone-provider

collector-cluster-standalone-provider.ClusterStandaloneDataMonitor

 ,基于 H2 的 叢集管理實作。該實作是單機版,建議僅用于 SkyWalking 快速上手,生産環境不建議使用。項目結構如下 :

SkyWalking 源碼分析 —— Collector Cluster 叢集管理1. 概述2. collector-cluster-define3. collector-cluster-zookeeper-provider4. collector-cluster-standalone-provider5. collector-cluster-redis-provider

大體實作和 

collector-cluster-zookeeper-provider

 差不多,差異在對 DataMonitor 的實作類 ClusterStandaloneDataMonitor 上。

在 ClusterStandaloneDataMonitor 裡,實際并未使用 H2Client ,而是基于記憶體,胖友可以自己檢視下。

5. collector-cluster-redis-provider

collector-cluster-redis-provider

 :基于 Redis 的叢集管理實作。目前暫未完成。

繼續閱讀