Pinpoint Java/PHP Agent 实现

Pinpoint Java/PHP Agent的模拟实现

  • pinpoint的工作流图
  • pinpoint的agent的时序图
  • pinpoint的agent的启动流程
  • 模拟pinpoint的agent给收集器发送消息

pinpoint的工作流图:

getset

pinpoint中串联的整体时序图:

getset

pinpoint中定义的几个消息实体结构如图:

getset

Java Agent 模拟实现(纯学习,无代码,优雅实现请参考官方代码)

在bootstrap包中定义入口类PinpointBootStrap的入口方法premain:
getset

  • 检查加载状态
  • 优先加载核心包(instrumentation.appendToBootstrapClassLoaderSearch)
  • 启动pinpoint

PinpointStarter初始化将传入的agentArgs转为map:
getset

PinpointStarter启动时,先获取agent核心和基础包位置:
getset

PinpointStarter启动时,
记录日志位置到内存;
记录pinpoint版本到内存;
getset
加载插件类并注册到service工厂; 加载默认的监听处理类并注册到service工厂(ServerType和AnnotationKey)
getset

根据代理参数返回代理的实例
getset

初始化代理实例的时候会同时加载已经添加的过滤处理插件
getset

执行代理实例的start方法,启动tcp和udp发送消息的sender
getset

PHP Agent 模拟实现agent(真实目的来了)

主页面右上角可以看到当前请求的时间分布图:
getset

鼠标拖拽选中的散点可以显示散点的详细请求时间和相关参数:
通过下方的Server-Map可以看到当前这个请求的请求链路:
getset

通过下方的tab的callTree可以观测到详细的调用方法以及花费的调用时间:
getset

通过下方的tab的timeline可以观测到更详细的调用方法以及花费的调用时间:
getset

至于mixed view的tab展示的是综合的信息,包括jvm的调用信息(php咱未做jvm参数的封装模拟):
getset

如果部分接口调用异常,可以通过调用栈直接观测到异常的根源,定位问题,不需要再进行扫log等相关处理:
getset

pinpoint的agent的php代码实现

整体消息的发送流程;
三步:
00:服务注册到pinpoint的collector;
01:发送普通的http请求到java服务;
02:发送udp到collector,告诉pinpoint需要串联的消息和相关信息;
getset

生产TAgentInfo信息实例代码:
getset

生产TSpan信息实例的代码:
getset

发送TAgentInfo消息前需要进行消息头的设置;对接pinpoint的需要,pinpoint内部定义的消息协议头;
getset

封装了简单的http请求处理(需要注意的是增加Header的相关参数):
getset
getset

业务中处理不同的请求发送消息;每一条java请求后都需要进行消息的发送到pinpoint:
getset

其中采样比,也需要加入到Header中;

如果采样Header中需要传入:Pinpoint-Sampled:s1

如果通知下游不采样则传入:Pinpoint-Sampled:s0

总结

所有的目的只有一个,PHP系统可以接入Pinpoint,这是一个很好的开始!