• 1. 概述

  • 2. Collector 同步相关 API

    • 2.1 应用的同步 API

    • 2.2 操作的同步 API

  • 3. Agent 调用同步 API

    • 3.1 DictionaryManager

    • 3.2 PossibleFound



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 接口,操作名服务接口。

  • 定义了 `#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> 对象的创建。

  • `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 ,应用字典。

  • 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 时的处理逻辑接口。


©著作权归作者所有:来自51CTO博客作者mb5ff80520dfa04的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 基于Spring Boot实现图片上传/加水印一把梭操作
  2. linux系统重启操作系统后报错提示An error occurred during the
  3. linux系统操作系统网卡漂移解决方案及问题原因
  4. linux操作系统可以ping通ssh连接无响应
  5. 操作系统分配存储时网络无法正常连接
  6. 一篇文章完全掌握 JavaScript 数组操作[每日前端夜话0x87]
  7. C#基础入门第十二天(面向对象多态,File操作流,泛型集合)
  8. 安利 5 个拍案叫绝的 Matplotlib 骚操作!
  9. pandas100个骚操作:JSON自动解析为DataFrame

随机推荐

  1. Android将byte数组写入文件
  2. Android XML�O置屏幕方向(android:screenO
  3. 怎么让 Android 程序一直后台运行,像 QQ
  4. Android之View篇1————初识View
  5. ConstraintLayout 实现水平方向 权重 效
  6. 关于android的nfc问题
  7. 深入理解Android消息处理系统——Looper
  8. Android实习笔记----调用拨号器,邮件短信
  9. android O 对后台服务的限制
  10. Android(安卓)播放视频的方法+播放测试地