本文主要基于 SkyWalking 3.2.6 正式版
RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
您对于源码的疑问每条留言都将得到认真回复.甚至不知道如何读源码也可以请教噢.
新的源码解析文章实时收到通知.每周更新一篇左右.
认真的源码交流微信群.
1. 概述
2. Collector 同步相关 API
2.1 应用的同步 API
2.2 操作的同步 API
3. Agent 调用同步 API
666. 彩蛋
3.1 DictionaryManager
3.2 PossibleFound
RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
您对于源码的疑问每条留言都将得到认真回复.甚至不知道如何读源码也可以请教噢.
新的源码解析文章实时收到通知.每周更新一篇左右.
认真的源码交流微信群.
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」 非常相似,所以本小节,更多的是提供代码的链接地址.
,继承 Service 接口,操作名服务接口.
2.2.1 ServiceNameDiscoveryServiceHandler#discovery(…)
ServiceNameDiscoveryServiceHandler#discovery(ServiceNameCollection, StreamObserver < ServiceNameMappingCollection > ) ,根据操作名数组,查找操作编号数组.
2.2.2 IServiceNameService#getOrCreate(…)
org.skywalking.apm.collector.agent.stream.service.register.IServiceNameService
定义了 #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 对象的创建.
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" 双向递增.
org.skywalking.apm.collector.storage.table.register.ServiceName ,操作名.例如记录在 ES 如下图:
ServiceNameEsRegisterDAO#save(ServiceName)
2.2.4 ServiceName
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 时的处理逻辑接口.
来源: https://juejin.im/entry/5a568d295188257322589a21