分散式追蹤 & APM 系統 SkyWalking 源碼分析

1. 概述

本文主要分享 Agent DictionaryManager 字典管理。先來簡單了解下字典的定義和用途:

  • 字典實際上是一個 Map 映射。目前 Agent 上有兩種字典:應用編碼與應用編號的映射,操作名與操作編號的映射。

  • 應用的定義:例如,Tomcat 啟動的應用,或者程序里訪問的 MongoDB 、MySQL 都可以認為是應用。

  • 操作的定義:例如,訪問的 URL 地址,Mongo 的執行操作。

  • Agent 在每次上傳調用鏈路 Segment 給 Collector 時,Segment 裡面需要包含應用和操作相關信息。考慮到減少網路流量,應用編號少於應用編號,操作編號少於操作名。

Agent 字典,會定時從 Collector 【同步】需要( 需要的定義,下文代碼會看到 )的字典。

Advertisements

下面,我們分成兩個小節,分別從 API 的實現與調用,分享代碼的具體實現。

2. Collector 同步相關 API

Collector 同步相關 API 相關有四個介面:

  • 2.1 應用的同步 API

  • 2.2 操作的同步 API

API 處理的流程大體如下:

.

2.1 應用的同步 API

應用的同步 API ,實際使用的是應用的註冊 API。

2.2 操作的同步 API

我們先來看看 API 的定義,DiscoveryService,如下圖所示:

.

整體代碼和 「2.1 應用的同步 API」 非常相似,所以本小節,更多的是提供代碼的鏈接地址。

2.2.1 ServiceNameDiscoveryServiceHandler#discovery(…)

Advertisements

ServiceNameDiscoveryServiceHandler#discovery(ServiceNameCollection, StreamObserver<ServiceNameMappingCollection>),根據操作名數組,查找操作編號數組。

2.2.2 IServiceNameService#getOrCreate(…)

org.skywalking.apm.collector.agent.stream.service.register.IServiceNameService ,繼承Service 介面,操作名服務介面。

  • 定義了 #getOrCreate(applicationId, serviceName) 介面方法,根據應用編號 + 操作名字,獲取或創建操作名( ServiceName ),並獲得操作編號。

  • org.skywalking.apm.collector.agent.stream.worker.register.ServiceNameService ,實現 IServiceNameService 介面,操作名服務實現類。

  • 實現了 #getOrCreate(applicationId, serviceName)方法。

2.2.3 Graph#start(ServiceName)

在 #createServiceNameRegisterGraph() 方法中,我們可以看到 ServiceName 對應的Graph<ServiceName>對象的創建。教學資料加QQ:1728804959

  • org.skywalking.apm.collector.agent.stream.worker.register.ServiceNameRegisterRemoteWorker ,繼承 AbstractRemoteWorker 抽象類,操作名註冊遠程 Worker 。

  • org.skywalking.apm.collector.agent.stream.worker.register.ServiceNameRegisterSerialWorker ,繼承 AbstractLocalAsyncWorker 抽象類,非同步保存應用 Worker 。

  • 相同於 Application ,ServiceName 的操作編號,從 "1" 雙向遞增。

  • ServiceNameEsRegisterDAO#save(ServiceName)

2.2.4 ServiceName

org.skywalking.apm.collector.storage.table.register.ServiceName ,操作名。例如記錄在 ES 如下圖:

.

3. Agent 調用同步 API

在 《SkyWalking 源碼分析 —— 應用於應用實例的註冊》「3. Agent 調用註冊 API」 一文中,在 【第 170 至 173 行】的代碼,我們可以看到,AppAndServiceRegisterClient 會定時從 Collector 同步所有字典信息。

3.1 DictionaryManager

org.skywalking.apm.agent.core.dictionary.DictionaryManager ,字典管理器。目前管理有兩種字典:

  • ApplicationDictionary

  • OperationNameDictionary

3.1 ApplicationDictionary

org.skywalking.apm.agent.core.dictionary.ApplicationDictionary

,應用字典。教學資料加QQ:1728804959

  • INSTANCE

    枚舉屬性,單例。

  • applicationDictionary

    屬性,應用編碼與應用編號的映射。

  • unRegisterApplications

    屬性,未知應用編碼集合。Agent 會定時從 Collector 同步。這也是文章開頭說的,「需要」的定義。

#find(applicationCode)

方法,根據應用編碼,查詢應用編號。

  • 第 57 行:根據應用編碼,從

    applicationDictionary

    中,查詢應用編號。

  • 第 58 至 59 行:當應用編號查找到時,返回 Found 。Found 會在下文詳細解析。

  • 第 61 至 64 行:當應用編號查找不到時,添加到

    unRegisterApplications

    中,返回 NotFound 。NotFound 會在下文詳細解析。

#syncRemoteDictionary(ApplicationRegisterServiceGrpc.ApplicationRegisterServiceBlockingStub)

方法,調用 「2.1 應用的同步 API」 ,從 Collector 同步

unRegisterApplications

對應的應用編號集合。

3.2 OperationNameDictionary

org.skywalking.apm.agent.core.dictionary.OperationNameDictionary

,操作名字典。

和 ApplicationDictionary 基本類似,胖友點擊 代碼 ,自己閱讀理解。

3.2 PossibleFound

在分享 PossibleFound 之前,我們先來看一段代碼,了解該類的意圖:

  • 我們在使用

    XXXXDictionary#find(xxx)

    方法時,返回的會是 Found 或者 NotFound 。這兩個類本身是互斥的,並且繼承 PossibleFound 。在 PossibleFound 提供

    #doInCondition(method01, method02)

    方法,優雅的處理兩種情況。

org.skywalking.apm.agent.core.dictionary.PossibleFound ,抽象類,代碼如下:

  • found

    屬性,是否找到。

  • value

    屬性,找到的結果。

  • org.skywalking.apm.agent.core.dictionary.Found 實現 PossibleFound 類,

    found = true

    並且

    value

    為找到的值。

    org.skywalking.apm.agent.core.dictionary.NotFound 實現 PossibleFound 類,

    found = false

    並且

    value

    不賦值。

  • #doInCondition(Found, NotFound)

    方法,根據查找結果,執行不同的邏輯,【無返回】。

  • 第一個參數,PossibleFound.Found 介面,Found 時的處理邏輯介面。

  • 第二個參數,PossibleFound.NotFound 介面,NotFound 時的處理邏輯介面。

  • #doInCondition(FoundAndObtain, NotFoundAndObtain)

    方法,根據查找結果,執行不同的邏輯,【有返回】。

  • 第一個參數,PossibleFound.FoundAndObtain 介面,Found 時的處理邏輯介面。

  • 第二個參數,PossibleFound.NotFoundAndObtain 介面,NotFound 時的處理邏輯介面。

Advertisements

你可能會喜歡