1. 概述
本文主要分享 Collector Naming Server 命名服務。主要包含如下部分:
- Collector Naming Server 提供 Http 兩個接口,提供 Agent 分别查詢 Collector Agent Jetty Server 、Collector Agent gRPC Server 叢集。
- Collector Agent Jetty Server 、Collector Agent gRPC Server 叢集内部的注冊與發現。
友情提示,建議胖友已經讀過 《SkyWalking 源碼分析 —— Collector Server Component 伺服器元件》 、《SkyWalking 源碼分析 —— Collector Server Component 伺服器元件》
Collector Agent Server ( 包括 Jetty 和 gRPC ),提供上傳調用鍊路,JVM Metric 等等 API 給 Agent 調用。
Agent 通過 Collector Naming Server 調用 Collector Agent Server 的 API ,查詢 Collector Agent Server 最新的叢集位址。
Naming Server 在 SkyWalking 架構圖處于如下位置( 紅框 ) :
FROM https://github.com/apache/incubating-skywalking
下面我們來看看整體的項目結構,如下圖所示 :
2. Collector Naming Server
Collector Naming Server 通過
apm-collector-naming
項目實作,其中:
-
項目:定義了 Naming Server 的接口。collector-naming-define
-
項目:基于 Jetty Server 的 Naming Server 實作。collector-naming-jetty-provider
2.1 NamingModule
org.skywalking.apm.collector.cluster.ClusterModule
,實作 Module 抽象類,叢集管理 Module 。
#name()
實作方法,傳回子產品名為
"naming"
。
#services()
實作方法,傳回 Service 類名:NamingHandlerRegisterService 。
2.2 NamingModuleJettyProvider
org.skywalking.apm.collector.naming.jetty.NamingModuleJettyProvider
,實作 ModuleProvider 抽象類,基于 Jetty 的命名元件服務提供者實作類。
#name()
實作方法,傳回元件服務提供者名為
"jetty"
。
module()
實作方法,傳回元件類為 NamingModule 。
#requiredModules()
實作方法,傳回依賴元件為 ClusterModule 、JettyManagerModule。
#prepare(Properties)
實作方法,執行準備階段邏輯。
- 第 55 行 :建立 ZookeeperModuleListenerService / NamingJettyHandlerRegisterService 對象,并調用
父類方法,注冊到#registerServiceImplementation()
。services
#start()
實作方法,執行啟動階段邏輯。
- 第 65 行 :調用
方法,建立 Jetty Server ,此時不會啟動 Jetty Server。在JettyManagerService#createIfAbsent(host, port, contextPath)
方法,統一啟動所有 Jetty Server,在 《SkyWalking 源碼分析 —— Collector Jetty Server Manager》「3. JettyManagerProvider」 有詳細解析。JettyManagerProvider#notifyAfterCompleted()
#notifyAfterCompleted()
實作方法,執行啟動完成邏輯。目前是個空方法。
2.3 NamingHandlerRegisterService
org.skywalking.apm.collector.naming.service.NamingHandlerRegisterService
,繼承 Service 接口,命名處理器注冊服務接口。
#register(ServerHandler)
接口方法,注冊 Server 請求處理器。Collector Agent Server 會調用該方法,将其實作的 用于 Naming 的 ServerHandler 進行注冊。如下圖所示:
2.3.1 NamingJettyHandlerRegisterService
org.skywalking.apm.collector.naming.jetty.service.service.NamingJettyHandlerRegisterService
,基于 Jetty 的命名處理器注冊服務實作類。
#register(moduleName, providerName, registration)
實作方法,調用
JettyManagerService#addHandler(path, registration)
方法,注冊 Jetty Server 請求處理器。
2.3.2 AgentJettyNamingHandler
org.skywalking.apm.collector.agent.jetty.handler.naming.AgentJettyNamingHandler
,實作 JettyHandler 抽象類,Collector Agent Jetty Server 實作的命名處理器。
#pathSpec()
實作方法,獲得請求路徑為
"/agent/jetty"
。
#doGet()
實作方法,調用
AgentJettyNamingListener#getAddresses()
方法,獲得 Collector Agent Jetty Server 叢集位址。
-
基于 Collector Cluster 元件,實作了叢集位址變化的發現,在 《SkyWalking 源碼分析 —— Collector Cluster 叢集管理》 有詳細解析。org.skywalking.apm.collector.agent.jetty.handler.naming.AgentJettyNamingListener
2.3.3 AgentGRPCNamingHandler
org.skywalking.apm.collector.agent.grpc.handler.naming.AgentGRPCNamingHandler
,實作 JettyHandler 抽象類,Collector Agent gRPC Server 實作的命名處理器。
#pathSpec()
實作方法,獲得請求路徑為
"/agent/gRPC"
。
#doGet()
實作方法,調用
AgentGRPCNamingListener#getAddresses()
方法,獲得 Collector Agent gRPC Server 叢集位址。
-
基于 Collector Cluster 元件,實作了叢集位址變化的發現,在 《SkyWalking 源碼分析 —— Collector Cluster 叢集管理》 有詳細解析。org.skywalking.apm.collector.agent.grpc.handler.naming.AgentGRPCNamingListener
2.4 配置檔案
配置檔案如下 :
- 配置 Naming Server 啟動在 10800 端口。
- Naming Server 内嵌在 Collector Server 。通過啟動多個 Collector Server 節點,形成 Naming Server 叢集。Agent 配置多個 Naming Server 位址。
3. CollectorDiscoveryService
org.skywalking.apm.agent.core.remote.CollectorDiscoveryService
, 實作 Agent 的 BootService 接口,Collector Agent Server 位址發現服務。
#boot()
實作方法,調用
ScheduledExecutorService#scheduleAtFixedRate(...)
方法,建立定時任務。該定時任務無初始化延遲,每
Config.Collector.DISCOVERY_CHECK_INTERVAL
( 預設:60 s ) 執行一次。
- DiscoveryRestServiceClient 實作
接口,即建立的任務。java.lang.Runnable
3.1 CollectorDiscoveryService
org.skywalking.apm.agent.core.remote.CollectorDiscoveryService
,實作
java.lang.Runnable
接口,Collector 服務發現用戶端,基于 Rest 方式通信。
構造方法 ,首先随機選擇一個 Collector Naming Server ,用于下面
#findServerList()
方法,首次擷取 Collector Agent Server 叢集位址。
#run()
實作方法,調用
#findServerList()
方法,擷取 Collector Agent Server 叢集位址。
#findServerList()
方法,擷取 Collector Agent Server 叢集位址。
- 第 85 行 :建立
對象。目前使用 HttpClientorg.apache.http.impl.client.CloseableHttpClient
版本。4.5.3
- 第 87 行 :調用
方法,建立#buildGet()
對象。目前 Agent 查詢的是 Collector Agent gRPC Server 叢集位址,因為 gRPC 的性能相比 HTTP 更優秀。org.apache.http.client.methods.HttpGet
- 第 89 行 :向 Collector Naming Server 發起請求。
- 第 90 至 93 行 :當響應狀态碼非
時,調用200
方法,順序選擇 Collector Naming Server 清單的下一個。注意,此時不會再發起請求,需要等下一次執行。#findBackupServer()
- 第 95 至 111 行 :處理響應結果,若 Collector Agent gRPC Server 叢集位址發生變化,進行更新到
。RemoteDownstreamConfig.Collector.GRPC_SERVERS
- 第 114 至 117 行 :請求發生異常,調用
方法,順序選擇 Collector Naming Server 清單的下一個。#findBackupServer()
- 第 119 行 :調用
方法,進行關閉。CloseableHttpClient#close()
3.2 配置檔案
配置檔案如下 :
- 生産環境使用時,推薦 Agent 配置多個 Naming Server 位址。