APM(Application Performance Management)对应用程序性能和可用性的监控管理系统。它主要有这三个方面的内容,分别是 Logs(日志)、 Traces(链路追踪)和 Metrics(报表统计)。简单描述就是通过各种探针采集并上报数据,收集关键指标,同时搭配数据展示以实现对应用程序性能管理和故障管理的系统化解决方案。
1,低侵入性
监控系统应尽可能减少对业务系统的侵入,保持对使用方的透明性,减少开发人员的负担,降低接入门槛和难度。
2,低性能影响
由于全链路监控系统需要对各种应用中间件进行日志数据采集,大多都需要在业务系统内进行“埋点”或放置agent,一般都是在核心业务流程。因此应尽可能降低对业务系统造成的性能影响,对CPU的耗用和内存耗用都需要有一个参考阈值。并且APM系统的故障不能影响业务系统的正常使用。
3,时效性
实时有效的监控数据展示功能,帮助相关人员理解系统行为,为流程、架构、代码优化,以及扩容缩容、服务限流降级提供正确客观的数据参考。能对系统的反常阈值进行业务告警达到及时恢复处理的目的。
CAT:是由国内美团点评开源的,基于Java语言开发,目前提供Java、C/C++、Node.js、Python、Go等语言的客户端,监控数据会全量统计,国内很多公司在用,例如美团点评、携程、拼多多等,使用的时候,需要在应用程序中埋点,对代码侵入性强。
Zipkin:由Twitter公司开发并开源,Java语言实现,侵入性相对于CAT要低一点,需要对web.xml之类的配置文件做修改,依然对代码有侵入。
Pinpoint:一个韩国团队开源的产品,运用了字节码增强技术,只需要在启动时添加启动参数即可,对代码无侵入,目前支持Java和PHP语言,底层采用HBase来存储数据,探针收集的数据粒度非常细,但是性能损耗大,因其出现的时间较长,完成度也很高。
SkyWalking:国人开源的产品,主要开发人员来自于华为,2019年4月17日Apache董事会批准SkyWalking成为顶级项目,支持Java、.Net、NodeJs等探针,数据存储支持Mysql、Elasticsearch等,跟Pinpoint一样采用字节码注入的方式实现代码的无侵入,探针采集数据粒度粗,但性能表现优秀,且对云原生支持,目前增长势头强劲,社区活跃,中文文档没有语言障碍。
下面我们以SkyWalking来做全链路监控介绍
1,skywalking官网地址
https://skywalking.apache.org/
2,skywalking架构
SkyWalking 逻辑上分为四部分: 探针, 平台后端, 存储和用户界面.
1)探针:收集数据并重新格式化以符合SkyWalking的要求(不同的探针支持不同的来源)。
2)平台后端:支持数据聚合,分析和流处理,涵盖跟踪,指标和日志。
3)存储:是开放式的. 你可以选择一个既有的存储系统, 例如ElasticSearch,H2,MySQL,TiDB,InfluxDB, 也可以选择自己实现一个存储系统.
4)用户界面:是一个高度可定制的基于Web的界面,允许SkyWalking最终用户可视化和管理SkyWalking数据。
1,skywalking版本
apache-skywalking-apm-es7-8.4.0
启动skywalking
进入下载的skywalking,这里以window版本为例子,然后进入bin目录,双击startup.bat启动
稍等一会启动成功后,访问管理台地址,默认8080端口
http://127.0.0.1:8080/
整体界面如下
2,整合skywalking,以spirngboot为例,引入以下两个jar
org.apache.skywalking
apm-toolkit-logback-1.x
8.4.0
org.apache.skywalking
apm-toolkit-trace
8.4.0
3,与日志整合
这里以logback为例,%tid 就是skywalking ,链路id的占位符
${LOG_PATTERN}
4,探针数据采集
agent包在下载的skywalking这个目录下
\apache-skywalking-apm-bin-es7\agent
javaagent方式,在springboot项目启动参数加入agent启动项目
-javaagent:D:\apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=my-service
-Dskywalking.collector.backend_service=127.0.0.1:11800
-javaagent:skywalking的agent包位置
-Dskywalking.agent.service_name:应用上报的服务名称
-Dskywalking.collector.backend_service:skywalking接收agent发送采集数据的服务及端口
项目日志打印效果显示示例
到此,我们整合skywalking基本ok,可以监控应用的所有web请求。
但是skwalking目前的版本对异步线程和相关一些中间件的链路监控是无法通过agent方式把链路统一串联起来。所以下文继续介绍相关解决方案。
5,获取全局链路id
//代码中任何位置直接使用这个类获取当前线程的链路id
TraceContext.traceId();
6,异步线程链路打点
异步线程链路监控需要手工打点,这里有两种方式。一种是使用skywalking提供的包装类,RunnableWrapper和CallableWrapper。另一种是使用skywalking提供的注解TraceCrossThread.实际上我们看源代码可以知道RunnableWrapper和CallableWrapper实际上也是用注解TraceCrossThread来实现。以下是使用的代码示例。
//执行Runnable任务
public static void addTask(Runnable task) {
taskExecutor.execute(RunnableWrapper.of(task));
}
//Callable任务
public static Future addReturnedTask(Callable task){
return taskExecutor.submit(CallableWrapper.of(task));
}
@TraceCrossThread
public class MyRunnableClass implements Runnable{
@Override
public void run() {
}
}
7,相关中间件链路打点
对于rabbitmq和xxjob等中间件的链接监控,实际上目前版本的skywalking无法将链路串联起来。这个时候,我们可以用skywalking提供的注解@Trace,将方法的链路串联起来,间接达到对中间件链路监控的目的。
以下是rabbitmq消费者使用示例
@Trace
@RabbitListener(queues = RabbitMqConfig.QUEUE_A)
public void process(String content) {
log.info("接收处理队列A当中的消息:" + content);
}
rabbitmq消费者链路显示示例
8,常用用户界面
1)链路监控
通过日志打印的traceId或者请求路径,或者方法名进行快速定位链路
实际工作中用得最多。
2)cpu和内存和jvm等
3)全链路拓扑图
因笔者只启动了一个服务,所以看起来非常单调。