字节码的终极应用-GitHub高星开源APM项目之Pinpoint
大家好, 我们前面的章节javaagent以及一些字节码修改框架ASM和Javassist, 以及他们的一些简单的应用场景. 今天重点给大家介绍一款github上开源的APM分布式链路监控产品 -- Pinpoint.
Pinpoint是什么?
Pinpoint 是一个开源的APM (Application Performance Management/应用性能管理) 工具,用于基于java的大规模分布式系统。在使用上力图简单高效,通过在启动时安装 agent,不需要修改哪怕一行代码,最小化性能损失 (3%)。
中文参考文档:http://skyao.github.io/leaning-pinpoint/index.html
开源源码地址:https://github.com/naver/pinpoint
Pinpoint的特点
- 分布式事务跟踪,跟踪跨分布式应用的消息;
- 自动检测应用拓扑,帮助你搞清楚应用的架构;
- 水平扩展以便支持大规模服务器集群;
- 提供代码级别的可见性以便轻松定位失败点和瓶颈;
- 使用字节码增强技术,添加新功能而无需修改代码。
- pinpoint有非常直观的UI,符合项目的当前需求
- pinpoint是基于java开发的,利于项目后期对源代码的修改
- pinpoint的社区还是挺活跃,一般提问题第二天就有项目的 committer回复。
Pinpoint架构图
架构图对应说明:
- Pinpoint-Collector:收集各种性能数据
- Pinpoint-Agent:探针与应用服务器(例如tomcat)关联,部署到同一台服务器上
- Pinpoint-Web:将收集到的数据层现在web展示
- HBase Storage:收集到数据存到HBase中
演示Demo
准备工作
为了模拟分布式架构系统, 我们这里准备了三个springboot构建的项目, demoX, demoY, demoZ. 他们之间不仅会相会调用, 每个项目本身还会调用Kafka, Mysql, Redis等中间件. 我们假设他们之家的调用关系是这样的:
- demoX程序通过http协议调用demoY程序, 并访问Redis
private final String URL_Y = "http://localhost:18002/demoY/testY";
public String callY() {
return restTemplate.getForObject(URL_Y, String.class);
}
public void callRedis() {
redisTemplate.opsForValue().set("APM", "pinpoint");
}
- demoY通过http协议调用demoZ程序
public void callZ() {
restTemplate.getForObject(URL_Z, String.class);
}
public void sendMessage() {
kafkaTemplate.send("topic_z", "test message");
}
- demoZ程序查询Mysql数据库, 并通过json反序列化结果输出
@GetMapping("testZ")
public String testZ() {
SysLog sysLog = demoZService.callMysql();
return JSONObject.toJSONString(sysLog);
}
接入pinpoint
接入pinpoint无需修改任何源码, 只需在demoX, demoY, demoZ三个java进程启动的时候, 配置一个--javaagent的参数即可.
java -javaagent:D:/project/2.3.0-all/Assets/pinpoint-agent-2.3.0/pinpoint-bootstrap.jar -Dpinpoint.agentId=app_x_0810 -Dpinpoint.applicationName=app_x -Dpinpoint.profiler.profiles.active=local -jar demoX.jar
其中
-javaagent
用于指定pinpoint启动类包的位置-Dpinpoint.applicationName
用户指定接入pinpoint的应用名, 一会儿我们会在pinpoint的页面上看到.-Dpinpoint.agentId
用户指定pinpoint的进程名, 用户区分一个应用下的不同实例
启动成功, 会在日志中输出:
08-11 00:46:43.428 INFO PinpointStarter : pinpoint agent started normally.
监控数据查看
指标类数据
接入pinpoint之后,我们可以在页面上直观的看到jvm的各种指标数据, 比如CPU使用率, 堆内存大小, 堆内存使用量, GC次数, GC后的堆回收率等指标. 通过这些图表可以直观的反应当前应用的健康情况.
-
堆内存与GC图表
当前堆最大值125M, 已经使用50.7M, Major GC耗时128ms
-
非堆区域
-
CPU使用率
宿主机使用率9.8%, java进程使用率2.1%
Trace请求数据
Trace请求数据为当前java应用程序实时收到的外界的访问情况.从Trace数据中我们可以直观的看到当前系统的哪些接口被调用, 调用的次数, 接口的调用耗时, 是否存在异常等关键信息, 可以帮助运维和开发人员快速的定位和分析问题.
- 调用拓扑
如上面准备工作中的调用逻辑, 在pinpoint中可以直观的反应在调用拓扑中.
- 方法燃尽图
方法燃尽图是从方法的维度看某一次请求的耗时情况, 从该图中我们可以清洗的看到调用了哪些方法, 他们的耗时是多少. 对于业务开发人员来说, 通常可以一眼就看出哪些方法的耗时偏高.
- 堆栈明细
堆栈明细是从代码维度来看一次请求经过的所有应用和方法, 以及他们是如何调用了. 我们以请求经过的第一个应用demoX的堆栈明细为例, 请求首先进入Tocmat容器专门处理http请求的方法StandardHostValve.invoke(), 随后经过spring的框架方法FrameworkServlet.doGet(), 然后接下来是用户的业务Controller方法, Service方法, 在业务方法内部, 分别使用redis的set方法往redis中写入了数据, 随后又通过HTTP_Client_4工具发起了http调用, 请求的目的地是localhost:18002/demoY/testY, 也就是我们的demoY应用.如果你是一个有经验的开发人员, 你会一眼就发现调用redis的set方法居然花费了863ms, 这个显然是不符合预期的.
同理, demnY的堆栈:
demoZ的堆栈:
小结
本文我们介绍了一个开源的APM分布式链路监控工具Pinpoint.主要介绍了Pinpoint的架构和特点, 随后我们使用几个简单的demo模拟分布式调用的场景, 和大家一起分析了java应用采集到的各种监控指标, 主要分为Metric(指标数据)和Trace(请求数据). 希望对大家排查问题有一定的帮助.
本文由mdnice多平台发布