⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 http://www.iocoder.cn/SkyWalking/agent-dictionary/ 「芋道源码」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

1. 概述

本文主要分享 Agent DictionaryManager 字典管理。先来简单了解下字典的定义和用途:

  • 字典实际上是一个 Map 映射。目前 Agent 上有两种字典:应用编码与应用编号的映射,操作名与操作编号的映射。
    • 应用的定义:例如,Tomcat 启动的应用,或者程序里访问的 MongoDB 、MySQL 都可以认为是应用。
    • 操作的定义:例如,访问的 URL 地址,Mongo 的执行操作。
  • Agent 在每次上传调用链路 Segment 给 Collector 时,Segment 里面需要包含应用和操作相关信息。考虑到减少网络流量,应用编号少于应用编号,操作编号少于操作名。

Agent 字典,会定时从 Collector 【同步需要( 需要的定义,下文代码会看到 )的字典。

下面,我们分成两个小节,分别从 API 的实现调用,分享代码的具体实现。

2. Collector 同步相关 API

Collector 同步相关 API 相关有四个接口:

  • 2.1 应用的同步 API
  • 2.2 操作的同步 API

API 处理的流程大体如下:

2.1 应用的同步 API

应用的同步 API ,实际使用的是应用的注册 API,在 「2.1 应用的注册 API」 有详细解析。

2.2 操作的同步 API

我们先来看看 API 的定义,DiscoveryService ,如下图所示:

整体代码和 「2.1 应用的同步 API」 非常相似,所以本小节,更多的是提供代码的链接地址。

2.2.1 ServiceNameDiscoveryServiceHandler#discovery(...)

ServiceNameDiscoveryServiceHandler#discovery(ServiceNameCollection, StreamObserver<ServiceNameMappingCollection>),根据操作名数组,查找操作编号数组。

2.2.2 IServiceNameService#getOrCreate(...)

org.skywalking.apm.collector.agent.stream.service.register.IServiceNameService ,继承 Service 接口,操作名服务接口。

org.skywalking.apm.collector.agent.stream.worker.register.ServiceNameService ,实现 IServiceNameService 接口,操作名服务实现类。

2.2.3 Graph#start(ServiceName)

#createServiceNameRegisterGraph() 方法中,我们可以看到 ServiceName 对应的 Graph<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 ,应用字典。

  • 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抽象类,代码如下:

666. 彩蛋

知识星球

写水文,好枯燥。

胖友,分享个朋友圈可好?

文章目录
  1. 1. 1. 概述
  2. 2. 2. Collector 同步相关 API
    1. 2.1. 2.1 应用的同步 API
    2. 2.2. 2.2 操作的同步 API
      1. 2.2.1. 2.2.1 ServiceNameDiscoveryServiceHandler#discovery(...)
      2. 2.2.2. 2.2.2 IServiceNameService#getOrCreate(...)
      3. 2.2.3. 2.2.3 Graph#start(ServiceName)
      4. 2.2.4. 2.2.4 ServiceName
  3. 3. 3. Agent 调用同步 API
    1. 3.1. 3.1 DictionaryManager
      1. 3.1.1. 3.1 ApplicationDictionary
      2. 3.1.2. 3.2 OperationNameDictionary
  4. 4. 3.2 PossibleFound
  5. 5. 666. 彩蛋