文章40 | 阅读 30642 | 点赞0
本文主要分享 Agent DictionaryManager 字典管理。先来简单了解下字典的定义和用途:
字典实际上是一个 Map 映射。目前 Agent 上有两种字典:应用编码与应用编号的映射,操作名与操作编号的映射。
应用的定义:例如,Tomcat 启动的应用,或者程序里访问的 MongoDB 、MySQL 都可以认为是应用。
操作的定义:例如,访问的 URL 地址,Mongo 的执行操作。
Agent 在每次上传调用链路 Segment 给 Collector 时,Segment 里面需要包含应用和操作相关信息。考虑到减少网络流量,应用编号少于应用编号,操作编号少于操作名。
Agent 字典,会定时从 Collector 【同步】需要( 需要的定义,下文代码会看到 )的字典。
下面,我们分成两个小节,分别从 API 的实现与调用,分享代码的具体实现。
Collector 同步相关 API 相关有四个接口:
API 处理的流程大体如下:
应用的同步 API ,实际使用的是应用的注册 API,在 「2.1 应用的注册 API」 有详细解析。
我们先来看看 API 的定义,DiscoveryService
,如下图所示:
整体代码和 「2.1 应用的同步 API」 非常相似,所以本小节,更多的是提供代码的链接地址。
ServiceNameDiscoveryServiceHandler#discovery(ServiceNameCollection, StreamObserver<ServiceNameMappingCollection>)
,根据操作名数组,查找操作编号数组。
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)
方法。在 #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)
org.skywalking.apm.collector.storage.table.register.ServiceName
,操作名。例如记录在 ES 如下图:
在 《SkyWalking 源码分析 —— 应用于应用实例的注册》「3. Agent 调用注册 API」 一文中,在 【第 170 至 173 行】的代码,我们可以看到,AppAndServiceRegisterClient 会定时从 Collector 同步所有字典信息。
org.skywalking.apm.agent.core.dictionary.DictionaryManager
,字典管理器。目前管理有两种字典:
org.skywalking.apm.agent.core.dictionary.ApplicationDictionary
,应用字典。
INSTANCE
枚举属性,单例。applicationDictionary
属性,应用编码与应用编号的映射。unRegisterApplications
属性,未知应用编码集合。Agent 会定时从 Collector 同步。这也是文章开头说的,“需要”的定义。#find(applicationCode)
方法,根据应用编码,查询应用编号。
applicationDictionary
中,查询应用编号。unRegisterApplications
中,返回 NotFound 。NotFound 会在下文详细解析。#syncRemoteDictionary(ApplicationRegisterServiceGrpc.ApplicationRegisterServiceBlockingStub)
方法,调用 「2.1 应用的同步 API」 ,从 Collector 同步 unRegisterApplications
对应的应用编号集合。
org.skywalking.apm.agent.core.dictionary.OperationNameDictionary
,操作名字典。
和 ApplicationDictionary 基本类似,胖友点击 代码 ,自己阅读理解。
在分享 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://blog.csdn.net/weixin_42073629/article/details/119703551
内容来源于网络,如有侵权,请联系作者删除!