当前位置 : 首页 » 文章分类 :  开发  »  Pinpoint

Pinpoint

Pinpoint 是用Java 编写的大型分布式系统的APM(应用性能管理)工具,或者称为调用链跟踪系统、分布式跟踪系统,通过 JavaAgent 的机制来做字节码代码植入,追踪每个请求的完整调用链路,收集调用链路上每个服务的性能数据。
https://github.com/naver/pinpoint

APM监控–(五)pinpoint使用手册
https://blog.csdn.net/xvshu/article/details/79866237


Pinpoint

Pinpoint 主要由 3 个组件外加 Hbase 数据库组成,三个组件分别为:Agent、Collector 和 Web UI。

调用链跟踪原理

无论 Pinpoint 还是 Zipkin,其实现都是基于 Google Dapper 的论文。其核心思想就是在服务各节点彼此调用的时候,记录并传递一个应用级别的标记,这个标记可以用来关联各个服务节点之间的关系。

比如两个节点之间使用 HTTP 作为请求协议的话,那么这些标记就会被加入到 HTTP header 中。因此如何传递这些标记是与节点之间使用的通讯协议有关的,有些协议就很容易加入这样的内容,但有些协议就相对困难甚至不可能,因此这一点就直接决定了实现分布式追踪系统的难度。


Pinpoint agent原理

pinpoint 通过字节码增强技术(有的叫动态探针技术)来实现无侵入式的调用链采集。其核心实现原来还是基于 JVM 的 javaagent 机制来实现。
pinpoint在启动时通过设置
-javaagent:$AGENT_PATH/pinpoint-bootstrap-$VERSION.jar
来指定 pinpoint agent 加载路径,在启动的时候 agent 将在加载应用 class 文件之前做拦截并修改字节码,在 class 方法调用的前后加上链路采集逻辑,从而实现链路采集功能。

javaAgent 的底层机制主要依赖 JVMTI, JVMTI 全称 JVM Tool Interface,是 JVM 暴露出来的一些供用户扩展的接口集合。JVMTI 是基于事件驱动的,JVM 每执行到一定的逻辑就会调用一些事件的回调接口(如果有的话),这些接口可以供开发者扩展自己的逻辑。但 JVMTI 都是一些接口合集,需要有接口的实现,这就用到了 java 的 instrument,可以理解 instrument 是 JVMTI 的一种实现,为 JVM 提供外挂支持。

instrument 支持启动时加载和运行时加载两种方式,分别实现 JVMTI 的 Agent_OnLoad 和 Agent_OnAttach 方法;
pinpoint目前采用的是启动时加载方式

1、Pinpoint Agent 类必须打成 jar 包,然后里面的 META-INF/MAINIFEST.MF 必须包含 Premain-Class 这个属性

Manifest-Version: 1.0
Premain-Class: com.navercorp.pinpoint.bootstrap.PinpointBootStrap
Archiver-Version: Plexus Archiver
Built-By: user
Can-Redefine-Classes: true
Pinpoint-Version: 1.6.0-SNAPSHOT
Can-Retransform-Classes: true
Created-By: Apache Maven 3.5.2
Build-Jdk: 1.8.0_152

2、启动类中实现 instrument 规定的 premain 方法(PinpointBootStrap.java),应用在启动前会优先调用这个方法。

public static void premain(String agentArgs, Instrumentation instrumentation) {
  ...
}

agentArgs 是 premain 函数得到的程序参数,随同 -javaagent 一起传入。
instrumentation 是一个 java.lang.instrument.Instrumentation 的实例,由 JVM 自动传入。java.lang.instrument.Instrumentation 是 instrument 包中定义的一个接口,也是这个包的核心部分,集中了其中几乎所有的功能方法,例如类定义的转换和操作等等。

pinpoint agent 字节码增强工作流程:


Pinpoint agent 工作流程

1、JVM 初始化并通过 System ClassLoader 加载 Pinpoint Agent 类;创建 Instrumentation 接口实例并调用 Pinpoint Agent 的 Premain 方法,并自动传入 Instrumentation 实例;
2、Pinpoint Agent 加载 plugins 插件,将其中的 transformer 类注册到 Instrumentation 实例中;
3、System ClassLoader 加载其他的应用 Java 类,此时将调用注册的 transformer 方法对要加载的 java 类进行字节码转换;
4、JVM 将转换后的 class 放入方法区。

pinpoint字节码增强技术原理
https://blog.csdn.net/wang_wpw/article/details/80917012


SpanId 和 TxId

Pinpoint 消息的数据结构主要包含三种类型 Span,Trace 和 TraceId。

Span 是最基本的调用追踪单元,当远程调用到达的时候,Span 指代处理该调用的作业,并且携带追踪数据。为了实现代码级别的可见性,Span 下面还包含一层 SpanEvent 的数据结构。每个 Span 都包含一个 SpanId。

Trace 是一组相互关联的 Span 集合,同一个 Trace 下的 Span 共享一个 TransactionId,而且会按照 SpanId 和 ParentSpanId 排列成一棵有层级关系的树形结构。

TraceId 是 TransactionId, SpanId 和 ParentSpanId 的组合。

  • TransactionId(TxId)是一个交易下的横跨整个分布式系统收发消息的 ID,其必须在整个服务器组中是全局唯一的。也就是说 TransactionId 识别了整个调用链
  • SpanId(SpanId)是处理远程调用作业的 ID,当一个调用到达一个节点的时候随即产生;
  • ParentSpanId(pSpanId)顾名思义,就是产生当前 Span 的调用方 Span 的 ID。如果一个节点是交易的最初发起方,其 ParentSpanId 是 -1,以标志其是整个交易的根 Span。

Pinpoint配置和使用

采样率配置

与 Google 的 dapper 自动调节采样频率不同的是,pinpoint 支持在配置文件自定义采样率,对应配置文件为 agent 的 pinpoint.config,默认 profiler.sampling.rate=1 表示全部采样,设置为 10 表示只采样 1/10 的请求。

# 1 out of n transactions will be sampled where n is the rate. (20: 5%)
profiler.sampling.rate=1

SpringBoot配置Pinpoint客户端代理

下载客户端代理 pinpoint-agent-1.8.5.tar.gz
https://github.com/naver/pinpoint/releases

新建目录:mkdir pp-agent
将 pinpoint-agent-1.6.0-SNAPSHOT.tar.gz 拷贝到 pp-agent 目录并解压
解压后里面有个配置文件 pinpoint.config, 配置项 profiler.collector.ip=127.0.0.1 这是指 pinpoint-collector 收集服务器的地址,如果是同一服务器,则不用修改。其它默认。

PP-Agent 作为一个 Java 探针 attach 在一个应用程序上(如Tomcat)。
要连接 Agent,在运行应用程序时,需要将 $AGENT_PATH/pinpoint-bootstrap-$VERSION.jar 传递给 -javaagent JVM参数:
-javaagent:$AGENT_PATH/pinpoint-bootstrap-$VERSION.jar
此外,PP-Agent需要2个命令行参数,以便在分布式系统中标识它自身:
-Dpinpoint.applicationName applicationName 表示同一种应用,整体长度不超过 20 个字符。例如:myservice-test
-Dpinpoint.agentId 唯一标识正在运行 Agent 的应用程序实例。同一个应用的不同实例应该使用不同的 agentId,相同的 applicationName。整体长度不超过20个字符。例如:myservice-test-001
agentId 必须是全局唯一的才能标识应用程序实例。并且共享同一applicationName的所有应用程序都被视为单个服务的多个实例。

1、SpringBoot Example
在 java -jar 的启动命令中加入 -javaagent, -Dpinpoint.agentId, -Dpinpoint.applicationName
例:

nohup java -javaagent:/Users/acheron/pinpoint/pp-agent/pinpoint-bootstrap-1.6.0.jar -Dpinpoint.agentId=myservice-001 -Dpinpoint.applicationName=myservice -jar myapp.jar &

2、Tomcat Example
增加 -javaagent, -Dpinpoint.agentId, -Dpinpoint.applicationName 到 Tomcat启动脚本 (catalina.sh) 的CATALINA_OPTS中:
例:

CATALINA_OPTS="$CATALINA_OPTS -javaagent:/data/pp-agent/pinpoint-bootstrap-1.8.3.jar"
CATALINA_OPTS="$CATALINA_OPTS -Dpinpoint.agentId=mer-orderM-prod-046"
CATALINA_OPTS="$CATALINA_OPTS -Dpinpoint.applicationName=mer-order-middle-prod"

分布式跟踪工具Pinpoint技术入门
http://www.herohuang.com/2017/03/01/apm-pinpoint/

docker部署pinpoint,监控docker中的Springboot项目
https://cloud.tencent.com/developer/article/1384079


常用APM工具

APM(Application Performance Management) ,应用性能管理, 目前市面的系统基本都是参考 Google 的 Dapper (大规模分布式系统的跟踪系统)来做的,通过跟踪请求的处理过程,来对应用系统在前后端处理、服务端调用的性能消耗进行跟踪。

Dapper,大规模分布式系统的跟踪系统
http://bigbully.github.io/Dapper-translation/

Pinpoint

1、Pinpoint
http://naver.github.io/pinpoint/
github地址: https://github.com/naver/pinpoint
是用JAVA开发的,在这个项目的主页还有些别的监控项目也不错https://github.com/naver/,这个是通过JavaAgent的机制来做字节码代码植入,实现加入traceid和抓取性能数据的目的。
NewRelic、Oneapm之类的工具在java平台上的性能分析也是类似的机制。

基本不用修改源码和配置文件,只要在启动命令里指定javaagent参数即可

Zipkin

2、Zipkin
官网: https://zipkin.io/
github地址: https://github.com/openzipkin/zipkin
这个是twitter开源出来的,也是参考Dapper的体系来做的。

Zipkin的java应用端是通过一个叫Brave的组件来实现对应用内部的性能分析数据采集。
Brave的github地址:https://github.com/openzipkin/brave

这个组件通过实现一系列的java拦截器,来做到对http/servlet请求、数据库访问的调用过程跟踪。
然后通过在spring之类的配置文件里加入这些拦截器,完成对java应用的性能数据采集。

需要对Spring、web.xml之类的配置文件做修改,相对麻烦一些

CAT

3、CAT
github地址:https://github.com/dianping/cat
这个是大众点评开源出来的,实现的功能也还是蛮丰富的,国内也有一些公司在用了。
不过他实现跟踪的手段,是要在代码里硬编码写一些“埋点”,也就是侵入式的。
这样做有利有弊,好处是可以在自己需要的地方加埋点,比较有针对性;坏处是必须改动现有系统,很多开发团队不愿意。

因为需要修改源码设置埋点,因此基本不太可能由运维人员单独完成,而必须由开发人员的深度参与了,而很多开发人员是比较抗拒在代码中加入这些东西滴;

SkyWalking

4、SkyWalking
github地址:https://github.com/apache/incubator-skywalking
这也是一个对JAVA分布式应用程序集群的业务运行情况进行追踪、告警和分析的系统。


APM和传统监控的区别

相对于传统的监控软件(Falcon、Zabbix)的区别,APM 更关注在对于系统内部执行、系统间调用的性能瓶颈分析,这样更有利于定位到问题的具体原因,传统监控软件只提供一些零散的监控点和指标,就算告警了也不知道问题是出在哪里。

APM 和监控系统还是有差别的。监控系统比较简单,只是发现你的系统故障,然后给你报个警。APM 算是完整的解决方案,不仅发现问题,给你告警,还给你定位具体的问题在哪里。现在大家都说端到端,就是 APM 的一个特点,从用户端呈现的问题,找到服务端具体是哪段代码不对。


上一篇 Flyway

下一篇 Kubernetes/K8S-基础

阅读
评论
2.7k
阅读预计10分钟
创建日期 2019-10-14
修改日期 2020-06-21
类别
标签

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论