Pinpoint中agent各个端口数据发送的过程

https://blog.csdn.net/wslyk606/article/details/77965073

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()); // DefaultAgent 197行

-- 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()); DefaultAgent 200行

-- 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 //DefaultAgent 413行

 

-- 真实发送AgentInfo数据的代码 ,TCP端口发送,而且是一个定时发送

dataSender.request(this.agentInfo, this.agentInfoSenderListener); //AgentInfoSender 200行

this.agentInfo是通过createTAgentInfo()来获取的。

this.agetnInfo = createTAgentInfo(); //AgentInfoSender 195行

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 服务的名字

|-- serviceLibsList<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);// AgentStatMonitor88行

把这个线程类添加到一个定时器中去执行.数据就开始采集了

 

TAgentStat 这个是一个集合的方式发送的,默认是要6个TAgentStat后才统一发送封装的对象是TAgentStatBatch,调用发送的方法是sendAgentStats();//AgentStatMonitor 214行

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 230行

 

 

TApiMetaData数据发送过程,这个主要主要是封装了API信息,通过TCP数据发送。简单说明下这个数据发送的作用,我们在后面的Tspan中有一个apiId,而我们最后要找到api的名字描述等内容,我们就是通过这个来实现的。

通过TraceContext.cacheApi(MethodDescriptor methodDescriptor)就能发送api的信息 //DefaultTranceContext.java 212行

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记录下来

}

 

booleancom.navercorp.pinpoint.profiler.context.DefaultCachingSqlNormalizer.normalizedSql(ParsingResult parsingResult)

简单说一下这个方法的作用就是把一个ParsingResult 转成一个通用的ParsingResultInternal中间设置的通过

NormalizedSql 可以看这个方法NormalizedSqlcom.navercorp.pinpoint.common.util.DefaultSqlParser.normalizedSql(String sql)用来解析。

TSqlMetaData

|-- agentId agentId

|-- agentStartTime TraceContext来获得agent开始时间

|-- sqlId sql预警的Id

|-- sql 对应的sql字符串

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值