一、APM
1、 什么是APM
APM (Application Performance Management) 即应用性能管理,属于IT运维管理(ITOM)范畴。主要是针对企业 关键业务的IT应用性能和用户体验的监测、优化,提高企业IT应用的可靠性和质量,保证用户得到良好的服务,降 低IT总拥有成本(TCO)。
APM(ApplicationPerformanceManagement)是一种应用性能监控工具,通过汇聚业务系统各处理环节的实时数据,分析业务系统各事务处理的交易路径和处理时间,实现对应用的全链路性能监测。目前主流的APM工具,基本都是参考了Google的Dapper(大规模分布式系统的跟踪系统)体系,通过跟踪业务请求的处理过程,完成对应用系统在前后端处理、服务端调用的性能消耗跟踪,提供可视化的界面来展示对跟踪数据的分析。
APM工具与传统的性能监控工具的区别在于,不仅仅提供一些零散的资源监控点和指标,其主要关注在系统内部执行、系统间调用的性能瓶颈分析,这样更有利于定位到问题的具体原
2、分布式链路追踪规范:OpenTracing
Tracing 是在上世纪 90 年代就已出现的技术,但真正让该领域流行起来的还是源于 Google 的一篇 Dapper 论文。分布式追踪系统发展很快,种类繁多,但无论哪种组件,其核心步骤一般有 3 步:代码埋点、数据存储和查询展示,如下图所示为链路追踪组件的组成
为了解决不同的分布式追踪系统 API 不兼容的问题,诞生了 OpenTracing 规范。OpenTracing 是一个轻量级的标准化层,它位于应用程序/类库和追踪或日志分析程序之间。OpenTracing 提供了 6 种语言的中立工具:Go、JavaScript、Java、Python、Objective-C 和 C ++。如下图所示为 OpenTracing 的架构。它支持 Zipkin、LightStep 和 Appdash 等追踪组件,并且可以轻松集成到开源的框架中,例如 gRPC、Flask、Django 和 Go-kit 等。
2.1 OpenTracing 架构
OpenTracing 是一个 Library 库,定义了一套通用的数据上报接口,要求各个分布式追踪系统都来实现这套接口。这样一来,应用程序只需要对接 OpenTracing,而无需关心后端采用的到底是什么分布式追踪系统,因此开发者可以无缝切换分布式追踪系统,也使得在通用代码库增加对分布式追踪的支持成为可能。
OpenTracing 于 2016 年 10 月加入 CNCF 基金会,是继 Kubernetes 和 Prometheus 之后,第三个加入 CNCF 的开源项目。它是一个中立的(厂商无关、平台无关)分布式追踪的 API 规范,提供统一接口,可方便开发者在自己的服务中集成一种或多种分布式追踪的实现。
二、 工具介绍
2.1、Pinpoint
Pinpoint | Leading Open-Source APM [官网]
官网文档翻译 · pinpoint-学习笔记 [中文翻译]
Pinpoint是由一个韩国团队实现并开源,针对Java编写的大规模分布式系统设计,通过JavaAgent的机制做字节代码植入,实现加入traceid和获取性能数据的目的,对应用代码零侵入。
Pinpoint 是用 Java 编写的 APM(应用性能管理)工具,用于大规模分布式系统。在 Dapper(dapper.docx) 之后,Pinpoint 提供了一个解决方案,以帮助分析系统的总体结构以及分布式应用程序的组件之间是如何进行数据互联的。
- 特点
- 安装agent是无侵入的
- 对性能的影响非常小(只增加约3%资源利用率)
- 支持模块
- JDK6+
- Tomcate 6/7/8,Jetty 9
- Spring, Spring Boot
- Apache Http Client 3.x/4.x,JDK HttpConnector,GoogleHttpClinet,OkHttpClient,NingAsyncHttpClient
- Thrift Cliet,Thirft Service
- MySql,Oracle,MSSQL,CUBRID,DBCP,POSTGRESQL
- Arcus,Memcached,Redis
- IBATIS,MyBatis
- Gson,Jackson,Json Lib
- Log4j,Logback
- 构建要求
- JDK 6,7,8安装
- Maven 3.2.x+ 安装
- 环境变量设置:JAVA_6_HOME=JDK6目录,JAVA_7_HOME=JDK7目录,JAVA_8_HOME=JDK8目录
4.作用
- 服务器地图(ServerMap)通过可视化分布式系统的模块和他们之间的相互联系来理解系统拓扑。点击某个节点会展示这个模块的详情,比如它当前的状态和请求数量。
- 实时活动线程图表(Realtime Active Thread Chart)实时监控应用内部的活动线程。
- 请求/应答分布图表(Request/Response Scatter Chart)长期可视化请求数量和应答模式来定位潜在问题。通过在图表上拉拽可以选择请求查看更多的详细信息。
- 调用栈(CallStack)在分布式环境中为每个调用生成代码级别的可视图,在单个视图中定位瓶颈和失败点。
- 巡查(Inspector)查看更多细节上的应用,如CPU使用率、内存/垃圾收集,TPS和JVM参数。
Pinpoint通过在Host App启动时加入PinpointAgent来采集数据,然后把采集到的跟踪数据和性能数据实时发送到PinpointCollector,Collector收集之后存放到HBase数据库中,由HBase做MapReduce运算,分析出分布式系统的机器访问关系拓扑图、每个节点的线程状态、请求/响应数据、调用栈信息、应用程序的性能数据,通过Pinpoint WebUI可以进行实时的展示
Pinpoint 链路监控页面
Pinpoint 的追踪数据粒度非常细,用户界面功能强大,Pinpoint 中的服务调用展示做得非常丰富,在这方面它优于市面上大多数组件。Pinpoint 使用 HBase 作为存储带 来了海量存储的能力。丰富的数据背后,必然需要大量的数据采集,因此在几款常用链路追踪组件中,Pinpoint 的探针性能最低,在生产环境需要注意应用服务的采样率,过高会影响系统的吞吐量。
另外,Pinpoint 目前仅支持 Java 和 PHP 语言,采用字节码增强方式去埋点,所以在埋点时不需要修改业务代码,是非侵入式的,非常适合项目已经完成之后再增加调用链监控的实践场景。Pinpoint 并不支持除 Java、PHP 语言之外的探针,在 Go 语言项目中应用需要基于 Pinpoint 进行二次封装开发。
优势:
- Java语言开发
- 开源,社区活跃
- 适合大规模数据量
- 社区活跃 start 12.4K
2.2、SkyWalking
演示地址:http://demo.skywalking.apache.org/general 账号/密码 skywalking
中文地址:https://github.com/SkyAPM/document-cn-translation-of-skywalking
【博客】 https://cloud.tencent.com/developer/article/173663
Skywalking是由国内一位叫吴晟的工程师开源,已加入Apache孵化器,是一个APM系统,为微服务架构和云原生架构系统设计。它通过探针自动收集所需的指标,并进行分布式追踪。通过这些调用链路以及指标,Skywalking APM会感知应用间关系和服务间关系,并进行相应的指标统计。Skywalking支持链路追踪和监控应用组件基本涵盖主流框架和容器,如国产PRC Dubbo和motan等,国际化的spring boot,spring cloud。
整个架构,分成上、下、左、右四部分:
- 上部分 Agent :负责从应用中,收集链路信息,发送给 SkyWalking OAP 服务器。目前支持 SkyWalking、Zikpin、Jaeger 等提供的 Tracing 数据信息。而我们目前采用的是,SkyWalking Agent 收集 SkyWalking Tracing 数据,传递给服务器。
- 下部分 SkyWalking OAP :负责接收 Agent 发送的 Tracing 数据信息,然后进行分析(Analysis Core) ,存储到外部存储器( Storage ),最终提供查询( Query )功能。
- 右部分 Storage :Tracing 数据存储。目前支持 ES、MySQL、Sharding Sphere、TiDB、H2 多种存储器。而我们目前采用的是 ES ,主要考虑是 SkyWalking 开发团队自己的生产环境采用 ES 为主。
- 左部分 SkyWalking UI :负责提供控台,查看链路等等。
功能列表
- 多种监控手段。可以通过语言探针和 service mesh 获得监控是数据。
- 多个语言自动探针。包括 Java,.NET Core 和 Node.JS。
- 轻量高效。无需大数据平台,和大量的服务器资源。
- 模块化。UI、存储、集群管理都有多种机制可选。
- 支持告警。
- 优秀的可视化解决方案。
优势
- 数据容器为ES,查询支持的维度较多并且扩展潜力大
- 项目设计采用微内核+插件,易读性和扩展性都比较强
- 主要的研发人员为华人并且均比较活跃,能够进行更加直接的沟通
- 拥有完整的APM和调用链跟踪功能
劣势
- 项目发展非常快,稳定性有待验证
- ES数据密度较小,在PB级别可能会有性能压力
- 缺少自定义指标的设计
- 有强依赖组件要求 搭建存储(h2,es),集群注册中心(Zookeeper、Kubernetes、Consul、Nacos),自建负载
2.3、Zipkin
官网:OpenZipkin · A distributed tracing system
Zipkin是由Twitter开源,是分布式链路调用监控系统,聚合各业务系统调用延迟数据,达到链路调用监控跟踪。Zipkin基于Google的Dapper论文实现,主要完成数据的收集、存储、搜索与界面展示。Java应用端的数据采集通过Brave组件来实现,Brave组件通过实现一系列的Java拦截器,来做到对http/servlet请求、数据库访问的调用过程跟踪,然后在spring之类的配置文件里加入这些拦截器,完成对Java应用的性能数据采集
Zipkin主要分为四个部分:
1)ZipkinCollector:采集数据传输到Collector之后,Collector负责校验数据、存储数据、为数据建立索引;
2)Storage:Zipkin的数据可以存储在Cassandra、ElasticSearch和MySQL中;
3)Query API:提供数据的查询和检索服务;
4)Web UI:可视化展示平台,用于展示跟踪数据。
优势:
- zipkin 平台成熟,有广泛的使用客户,社区活跃
- 使用Java编写,适合二次开发
- Zipkin都支持OpenTracing,OpenCensus和OpenTelemetry(这三大开放跟踪框架),并具有广泛的可扩展性选项和工具集成
缺陷:
- 灵活性低,系统比较老,模块化程度低
- 不适合变化较快的组织
- 效率损失较高
2.4、CAT
【官网】https://github.com/dianping/cat
CAT是由大众点评开源的项目,基于Java开发的实时应用监控平台,包括实时应用监控,业务监控,可以提供十几张报表展示。Cat的定位是实时监控平台,但与其说是监控平台,更像是个数据仓库,在数据仓库的基础上提供丰富的报表分析功能。CAT实现跟踪的手段是通过在代码里面增加一些“埋点”来记录自己需要的数据,是一个侵入式的项目,开发团队对此大都有抵触情绪。
CAT分客户端和服务器端,客户端使用cat接口向服务器端上报统一格式的日志信息。CAT的客户端是产生日志的地方(一般来说就是被监控的应用,上图中的应用节点),相应的服务器端则是接受日志、消费日志的地方(上图中的server节点),日志消费后生成会日志报表。
CAT 很大的优势是它是一个实时系统,CAT 大部分系统是分钟级统计,但是从数据生成到服务端处理结束是秒级别,秒级定义是48分钟40秒,基本上看到48分钟38秒数据,整体报表的统计粒度是分钟级;第二个优势,监控数据是全量统计,客户端预计算;链路数据是采样计算。
功能模块
- cat-client: 客户端,上报监控数据
- cat-consumer: 服务端,收集监控数据进行统计分析,构建丰富的统计报表
- cat-alarm: 实时告警,提供报表指标的监控告警
- cat-hadoop: 数据存储,logview 存储至 Hdfs
- cat-home: 管理端,报表展示、配置管理等
优势:
- 实时处理:信息的价值会随时间锐减,尤其是事故处理过程中
- 全量数据:全量采集指标数据,便于深度分析故障案例
- 高可用:故障的还原与问题定位,需要高可用监控来支撑
- 故障容忍:故障不影响业务正常运转、对业务透明
- 高吞吐:海量监控数据的收集,需要高吞吐能力做保证
- 可扩展:支持分布式、跨 IDC 部署,横向扩展的监控系统
- 有丰富的报表
缺陷:
- 需要埋点,侵入性较强
- 侧重对Java应用的监控
2.5 Uber Jaeger
Jaeger 是 CNCF 云原生项目之一,Jaeger 受 Dapper 和 OpenZipkin 的启发,由 Uber 开源的分布式追踪系统,兼容 Open Tracing API。它用于微服务的监控和排查,支持分布式上下文传播、分布式事务的监控、报错分析、服务的调用网络分析以及性能/延迟优化。Jaeger 的服务端使用 Go 语言实现,其存储支持 Cassandra、Elasticsearch 和内存,并提供了 Go、Java、Node、Python 和 C++ 等语言的客户端库。Jaeger 具有如下的特性:
- 高扩展性 Jaeger 后端的分布式设计,可以根据业务需求进行扩展。例如,Uber 任意一个 Jaeger 每天通常要处理数十亿个跨度。
- 原生支持 OpenTracing Jaeger 后端、Web UI 和工具库的设计支持 OpenTracing 标准。
- 通过跨度引用将轨迹表示为有向无环图(不仅是树)
- 支持强类型的跨度标签和结构化日志
- 通过行李支持通用的分布式上下文传播机制
- 支持多个存储后端 Jaeger 支持两种流行的开源 NoSQL 数据库作为跟踪存储后端:Cassandra 3.4+ 和 Elasticsearch 5.x / 6.x。
- 现代化 Web UI Jaeger Web UI 是使用流行的开源框架实现的。v1.0 中发布了几项性能改进,以允许 UI 有效处理大量数据,并能够显示上万跨度的链路跟踪。
- 支持云原生部署 Jaeger 后端支持 Docker 镜像部署。二进制文件支持各种配置方法,包括命令行选项,环境变量和多种格式(yaml、toml 等)的配置文件。可以方便地部署到 Kubernetes 集群。
- 可观察性 默认情况下,所有 Jaeger 后端组件均开放 Prometheus 监控(也支持其他指标后端)。使用结构化日志库 zap 将日志标准输出。
- 与 Zipkin 向后兼容 已经使用 Zipkin 库,如果我们要切换到 Jaeger,客户端也不必重写所有代码。Jaeger 通过在 HTTP 上接受 Zipkin 格式(Thrift 或 JSON v1 / v2)的跨度来提供与 Zipkin 的向后兼容性。从 Zipkin 后端切换到 Jaeger 后端变得很简单。
Jaeger 架构图
我们来分析一下 Jaeger 的架构图,Jaeger 主要由以下几部分组成:
- jaeger client:为不同语言实现了符合 OpenTracing 标准的 SDK。应用程序通过 API 写入数据,client library 把 trace 记录按照应用程序指定的采样策略传递给 jaeger-agent。
- jaeger-agent:它是一个监听在 UDP 端口上用以接收 span 数据的网络守护进程,它会将数据批量发送给 collector。它被设计成一个基础组件,部署到所有的宿主机上。jaeger-agent 将 client library 和 collector 解耦,为 client library 屏蔽了路由和发现 collector 的细节。
- jaeger-collector:接收 jaeger-agent 发送来的数据,然后将数据写入后端存储。jaeger-collector 被设计成无状态的组件,因此可以同时运行任意数量的 jaeger-collector。
- Data Store:后端存储被设计成一个可插拔的组件,支持将数据写入 Cassandra、Elastic Search。
- jaeger-query:接收查询请求,然后从后端存储系统中检索 trace 并通过 UI 进行展示。jaeger-query 是无状态的,我们可以启动多个实例,把它们部署在 Nginx 这样的负载均衡器后面。
Jaeger 链路监控页面
列表中展示了请求的追踪记录,每次请求的时间、涉及的服务名和 Span 数量。通过统计的散列图,可以很清楚地看到请求的响应时间分布。相比于 Zipkin,Jaeger 在界面上较为丰富,但是也无告警功能。
三、产品对比
产品名称 | 代码集成 | 数据存储 | 传输协议 | UI(性能分析报表) | 高可用 | 告警 | 支持语言 | 扩展性 | 新能损失 | 实现语言 | 备注 |
Pinpoint | javaAgent技术,代码侵入性低 | HBase | Thrift | 服务拓扑图 实时活动图 请求响应分布 调用栈信息 应用监控 | 支持, 底层依赖hbase实现 | 支持 | java php | 弱 | 高 | Java | 韩国开源 |
Skywalking | javaAgent技术,代码侵入性低 | ES,H2 | gRPC | 服务拓扑图 服务调用链路图 实时活动图 请求响应分布 JVM调用栈信息 应用监控 | 支持 | 支持 | Java, C# PHP Node.js Go | 一般 | 低 | go | 国内华为开源 |
Zipkin | 不提供,只提供日志格式 | Cassandra ES, MYSQL | Http/MQ | 服务拓扑图 服务调用链路图 应用监控 | 不支持 需要HA实现 | 不支持 | Java go Scala ruby js | 强 | 一般 | java | Twitter 开源 |
cat | 需要代码埋点,侵入成都高 | MYSQL | 代码运行时间和次数 服务调用链路 服务拓扑 JVM监控 | 支持 | Java, C/C++, Node.js, Python, Go | 一般 | java | 国内美团 | |||
Jaeger | 拦截请求,侵入 | UDP/Http | 不支持 | Java C# Go PHP | 强 | 一般 | go | CNCF 云原生项目 |