Pinpoint中agent各个端口数据发送的过程, 持续更新

Agent程序启动后会调用DefaultAgent中的构造去创建很多的初始化,而agent发送的数据初始化过程也是从这里开始的!DefaultAgent.java

DefaultAgent 加载 agent的信息( AgentInformation):
this.agentInformation = agentInformationFactory.createAgentInformation(typeResolver.resolve()); //195行
AgentInformation包含了:
|- agentId 自己配置的agentId
|- applicationName 自己配置的应用名
|- startTime Java虚拟机的启动时间
|- pid Java虚拟机实现的名称,@前面的字符串
|- machineName 主机名
|- hostIp 本机IP地址
|- jvmVersion JVM的版本
|- serverType ServiceType -- 比如描述这是一个Tomcat
|- agentVersion agent的版本信息
this.spanDataSender = createUdpSpanDataSender(this.profilerConfig.getCollectorSpanServerPort(), "Pinpoint-UdpSpanDataExecutor",
this.profilerConfig.getSpanDataSenderWriteQueueSize(), this.profilerConfig.getSpanDataSenderSocketTimeout(),
this.profilerConfig.getSpanDataSenderSocketSendBufferSize()); //200行
-- span数据发送模块的初始化,参数是【端口,线程名,写入队列的大小默认1024 * 5,设置超时时间默认1000 * 3, 发送缓冲的大小默认1024 * 64 * 16】
-- 这些值都是来自pinpoint.config中默认值在DefaultProfilerConfig.java文件中。
this.statDataSender = createUdpStatDataSender(this.profilerConfig.getCollectorStatServerPort(), "Pinpoint-UdpStatDataExecutor",
this.profilerConfig.getStatDataSenderWriteQueueSize(), this.profilerConfig.getStatDataSenderSocketTimeout(),
this.profilerConfig.getStatDataSenderSocketSendBufferSize()); //203行
-- AgentStatMonitor数据发送模块模块的初始化
DefaultTraceContext defaultTraceContext = createTraceContext();
-- 创建TraceContext
|-- 获取Trace currentRpcTraceObject() --> 插件开发的拦截器中就有使用
|-- 获取配置文件ProfilerConfig getProfilerConfig() --> 插件中要获取一些pinpoint.config的配置内容

this.tcpDataSender = createTcpDataSender(commandService); -- TCP数据发送者

this.agentInfoSender = new AgentInfoSender.Builder(tcpDataSender, this.agentInformation, jvmInformationFactory.createJvmInformation()).sendInterval(profilerConfig.getAgentInfoSendRetryInterval()).build();
agentInfo数据发送者this.agentInfoSender .start() ,就能创建一个周期性发送agentInfo!采用的是TCP

-- 真实发送AgentInfo数据的代码 ,TCP端口发送,而且是一个定时发送
dataSender.request(this.agentInfo, this.agentInfoSenderListener); //AgentInfoSender 200行
this.agentInfo是通过createTAgentInfo()来获取的。//AgentInfoSender 110行
TAgentInfo 一个包含了 AgentInformation 【agent信息】 + ServerMetaData 【服务元数据】+ JvmInformation 【jvm信息】信息的类,是thrift的可以序列化和反序列化的对象。
|-- ip ip, 通过 AgentInformation 中获得。
|-- hostname 主机名, 通过 AgentInformation 中获得。
|-- ports 端口,默认就是空字符串
|-- agentId agentId, 通过 AgentInformation 中获得。
|-- applicationName 应用名, 通过 AgentInformation 中获得。
|-- serviceType 只是serviceType的Code, 通过 AgentInformation 中获得getServerType ().getCode ()。
|-- pid Java虚拟机实现名称前面的整数值, 通过 AgentInformation 中获得。
|-- agentVersion agent的版本, 通过Version.VERSION 获得
|-- vmVersion 虚拟机的版本, 通过 AgentInformation 中获得。
|-- startTimestamp 无设置
|-- endTimestamp 无设置
|-- endStatus
|-- serverMetaData TServerMetaData,通过createTServiceInfo()来调用。serverMetaData不为空的时候才会设置,默认是没有的serverMetaData的设置又是通过publishServerMetaData(ServerMetaData serverMetaData)来实现。
|-- serverInfo 服务器信息,通过serverMetaData.getServerInfo()获得
|-- vmArgs 服务器的参数,通过serverMetaData.getVmArgs()获得
|-- serviceInfos List < TServiceInfo >
|-- serviceName 服务的名字
|-- serviceLibs List<String> 服务的lib

serverMetaData 主要就是把一个ServerMetaData转换成一个TServerMetaData,TServerMetaData是一个可以序列化是实例对象。下面 serviceInfos也是如此。
|-- jvmInfo 这是一个JVM的基本信息,createTJvmInfo()来处理。这里也是和上面一样的,也只是一个普通的JvmInfo对象转成TJvmInfo对象而已
|-- version 版本
|-- vmVersion 虚拟机的版本
|-- gcType 垃圾回收机制的类型

this.agentStatMonitor = new AgentStatMonitor(this.statDataSender, this.agentInformation.getAgentId(), this.agentInformation.getStartTime(), agentStatCollectorFactory); -- 创建 AgentStatMonitor,通过this.statDataSender来发送数据的,AgentStatMonitor主要是一个agent状态监听器,用来检测agent的信息的。this.agentStatMonitor.start()开始启动。//DefaultAgent的 451行
调用start()后。穿件CollectJob这是一个线程类CollectJob job = new CollectJob(this.numCollectionsPerBatch);// AgentStatMonitor 88行
把这个线程类添加到一个定时器中去执行.数据就开始采集了

TAgentStat 这个是一个集合的方式发送的,默认是要6个TAgentStat后才统一发送封装的对象是TAgentStatBatch,调用发送的方法是sendAgentStats(); //AgentStatMonitor 159行
TAgentStatBatch
|-- agentId agentId
|-- startTimestamp agent信息的时间
|-- agentStats List<TAgentStat> TAgentStat的集合
|-- TJvmGc 垃圾回收机制 final TJvmGc gc = garbageCollector.collect(); //AgentStatMonitor 148行中获得
|-- TJvmGcType Gc的类型UNKNOWN(0),SERIAL(1),PARALLEL(2), CMS(3),G1(4);
|-- jvmMemoryHeapUsed 堆的使用大小
|-- jvmMemoryHeapMax
|-- jvmMemoryNonHeapUsed
|-- jvmMemoryNonHeapMax
|-- jvmGcOldCount
|-- jvmGcOldTime
|-- TJvmGcDetailed 垃圾回收机制详细
|-- jvmGcNewCount
|-- jvmGcNewTime
|-- jvmPoolCodeCacheUsed
|-- jvmPoolNewGenUsed
|-- jvmPoolOldGenUsed
|-- jvmPoolSurvivorSpaceUsed
|-- jvmPoolPermGenUsed
|--jvmPoolMetaspaceUsed
|-- TCpuLoad CPU信息
|-- jvmCpuLoad
|-- systemCpuLoad
|-- TTransaction
|-- sampledNewCount
|-- sampledContinuationCount
|-- unsampledNewCount
|-- unsampledContinuationCount
|-- TActiveTrace
|-- TActiveTraceHistogram
|-- version
|-- histogramSchemaType
|-- activeTraceCount
|-- timestamp 当前时间
|-- collectInterval 采集间隔
数据发送的代码是:dataSender.send(agentStatBatch);// AgentStatMonitor 174行


TApiMetaData数据发送过程,这个主要主要是封装了API信息,通过TCP数据发送。 简单说明下这个数据发送的作用,我们在后面的Tspan中有一个apiId,而我们最后要找到api的名字描述等内容,我们就是通过这个来实现的。
通过TraceContext.cacheApi ( MethodDescriptor methodDescriptor)就能发送api的信息
ServletAsyncMethodDescriptor就是一个自定定义的类,这个类要实现MethodDescriptor。这个类主要是用来描述api的信息的,比如:apiId,类型,方法名、类名、参数类型、行号、全名、描述等内容可以参考tomcat插件中的 com . navercorp . pinpoint . plugin . tomcat .ServletAsyncMethodDescriptor
比如:在tomcat的插件中, StandardHostValveInvokeInterceptor的这个类就使用了这个插件。//82,83行

public int cacheApi(final MethodDescriptor methodDescriptor) {
final String fullName = methodDescriptor.getFullName(); //获取全名
final Result result = this.apiCache.put(fullName); //通过全面去获得Result,主要的目的是给这个方法名获得一个apiId,开始值是1来自增的数据,这个采用了缓存来处理,结果是传入的对象做键,result做值。可以看 com . navercorp . pinpoint . profiler . metadata .SimpleCache< T >

methodDescriptor.setApiId(result.getId()); //设置方法的apiId

if (result.isNewValue()) {//判断api星系是否是新的
final TApiMetaData apiMetadata = new TApiMetaData(); //可序列化的对象,api的元数据
apiMetadata.setAgentId(getAgentId()); //通过TraceContext来获得agentId
apiMetadata.setAgentStartTime(getAgentStartTime()); //通过TraceContext来获得开始时间

apiMetadata.setApiId(result.getId()); //方法的Id
apiMetadata.setApiInfo(methodDescriptor.getApiDescriptor()) ;//方法的描述信息
apiMetadata.setLine(methodDescriptor.getLineNumber()); //行号
apiMetadata.setType(methodDescriptor.getType()); //方法的类型

this.priorityDataSender.request(apiMetadata); //发送,通过的TCP,因为才创建TraceContext 的时候,地通过以下方法进行设置了发送数据对象defaultTraceContext.setPriorityDataSender(this.tcpDataSender);
}

return result.getId(); //最后还返回了api的Id
}

TApiMetaData
|-- agentId agentId
|-- agentStartTime TraceContext来获得agent开始时间
|-- apiId 方法的Id
|-- apiInfo 方法的描述信息
|-- line 行号
|-- type 类型

TStringMetaData数据发送过程,这个和TApiMetaData是相同的。记录字符串元数据
TStringMetaData
|-- agentId agentId
|-- agentStartTime TraceContext来获得agent开始时间
|-- stringId 字符串的id
|-- stringValue 字符串的值

TSqlMetaData数据发送过程,这个和TApiMetaData是相同的。记录Sql元数据,也可以简单理解为记录sql语句
public boolean cacheSql(ParsingResult parsingResult) {
if (parsingResult == null) {
return false;
}
// lazy sql parsing
boolean isNewValue = this.cachingSqlNormalizer.normalizedSql(parsingResult); // 对parsingResult进行解析,验证parsingResult 是否是新的
if (isNewValue) {
if (isDebug) {
logger.debug("NewSQLParsingResult:{}", parsingResult);
}
final TSqlMetaData sqlMetaData = new TSqlMetaData();
sqlMetaData.setAgentId(getAgentId()); //设置agentId
sqlMetaData.setAgentStartTime(getAgentStartTime()); //设置agent开始时间

sqlMetaData.setSqlId(parsingResult.getId()); //设置sqlId
sqlMetaData.setSql(parsingResult.getSql()); //设置sql字符串

this.priorityDataSender.request(sqlMetaData); //数据发送
}
return isNewValue; //通过返回值我们可以知道有没有把这个sql记录下来
}

boolean com . navercorp . pinpoint . profiler . context . DefaultCachingSqlNormalizer .normalizedSql( ParsingResult parsingResult)
简单说一下这个方法的作用就是把一个ParsingResult 转成一个通用的ParsingResultInternal中间设置的通过
NormalizedSql 可以看这个方法 NormalizedSql com . navercorp . pinpoint . common . util . DefaultSqlParser .normalizedSql( String sql)用来解析。
TSqlMetaData
|-- agentId agentId
|-- agentStartTime TraceContext来获得agent开始时间
|-- sqlId sql预警的Id
|-- sql 对应的sql字符串









  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值