全链路追踪系统
在微服务开发中,一次服务的调用也许会涉及多个依赖服务和团队。当线上出现问题时,通常需要多个团队配合定位,排查问题需要的时间较长,涉及的人员较广,这样排查问题的效率很低。全链路追踪系统就是为了解决这些问题而开发,有了该系统,可以在发生故障时能够快速定位问题并解决问题。
最为开发人员所熟知的全链路追踪系统是谷歌公司的 Dapper。谷歌公司开发 Dapper 系统是为了收集复杂的分布式系统的行为信息,大部分开源的分布式链路追踪系统都是基于 Dapper 的基本原理开发的。本文主要讲解全链路追踪系统的基本概念与技术框架。
全链路追踪系统的设计目标主要包含以下几点:
通过上面列出的设计目标可知,全链路追踪系统的主要功能如下:
如图 1 所示为一个 Span 链路信息图。如果 Span 没有父 Span,则它是根 Span。通过 Span id 与 Parent id 可以查询整个链路中的Span。同时,每个 Span 都封装了很多信息,如操作描述信息、时间戳信息及键值对(Tag)信息。

图1 Span链路图
如图 2 所示,一条链路只有一个 Trace id,每个 Span 就是链路中的节点,节点之间的连线使 Span 与父节点 Span 发生联系,每个 Span中保存了一些请求信息。

图2 Trace链路图
大部分开源调用链追踪系统都是参照 Dapper 这篇论文提出的模型进行实现的。
如图 3 所示为 Dapper 收集数据的过程。Dapper 对谷歌公司内部的通用框架都提供了装配工具,服务部署了这些装配工具后就会对调用链进行追踪,装配工具将追踪信息保存到机器的磁盘上,每台服务器上部署的 Dapper daemon 会将追踪信息收集到 Dapper Collector上。
Dapper Collector 根据各个服务上报的追踪信息中包含的 traceId、spanId 和 parentSpanId 组装成完整的调用链,同时注明每个环节的耗时,然后进行存储并提供查询功能。

图3 Dapper架构图

图4 Zipkin架构图
Zipkin 的整个架构与 Dapper 非常类似,它装配了追踪工具的服务:
其中,Transport 支持 HTTP、Kafka 等,Storage 存储支持 MySQL、Elasticsearch 和 Cassandra 等。Zipkin 的追踪是独立于开发语言的,只要满足 Zipkin 的追踪数据格式即可,它支持的框架包括 Grpc、Spring Web、Spring Boot 及 Spring Cloud 等。
如图 5 所示,Pinpoint 框架的基本组成部分与 Zipkin 相似:

图5 Pinpoint架构图
Pinpoint 使用字节码增强技术对服务进行埋点,追踪信息通过 Thrift 等方式上传到 Pinpoint Collector, Pinpoint 负责计算统计指标,并将实时结果和原始追踪信息都存入 HBase,前端 Web UI 从 HBase 中读数据进行展示查询。
Pinpoint 支持追踪的服务包括 Spring Boot、Thrift 和 Dubbo 等。它采用字节码增强技术侵入服务,业务无须修改代码,具有实时统计展示、JVM 实时监控及调用链追踪服务的特点。
Skywalking 跟 Pinpoint 一样,采用字节码注入的方式实现代码的无侵入,支持云原生,目前增长势头强劲,其架构如图 6 所示。

图6 Skywalking架构图
Skywalking 在逻辑上包含 4 部分,分别是:
此外,也可以通过日志采集方式进行追踪。Skywalking 的采集对吞吐量的影响比较小。
(1)根据要求下载 zipkin-server 的 JAR 包,然后在本地启动 Zipkin 的 Server 实例,启动命令如下:

图7 Zipkin主页面
(3)为本地服务添加 Zipkin 的相关依赖:

图8 查找Trace信息
(6)单击信息即可进入详情页面,如图 9 所示。

图9 Trace的详细信息
图 9 展示了一次请求中 Zipkin 统计的信息,包括响应时间、http.method、http.path、mvc.controller.class、mvc.controller.method、traceId、spanId 和 parentId 等。
下载并解压后,目录包含以下几个部分:
将环境变量设置为
图10 Skywalking UI页面
声明:《Java系列教程》为本站“54笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。
最为开发人员所熟知的全链路追踪系统是谷歌公司的 Dapper。谷歌公司开发 Dapper 系统是为了收集复杂的分布式系统的行为信息,大部分开源的分布式链路追踪系统都是基于 Dapper 的基本原理开发的。本文主要讲解全链路追踪系统的基本概念与技术框架。
基本特性
全链路追踪系统作为一个追踪监控系统,需要快速发现线上系统的故障,并能迅速定位故障位置,同时可以分析分布式系统中存在的性能瓶颈,从而辅助优化系统。这就要求全链路系统可以实时并全量地提供系统中的行为数据,做到高可用,并全面展现链路信息。全链路追踪系统的设计目标主要包含以下几点:
- 性能消耗低。调用链追踪应该对服务影响足够小,不应消耗太多的系统资源。
- 代码侵入低。作为中间件,应当尽可能少地侵入或者不侵入其他业务系统,保持对使用方的透明性,减少开发人员的负担和接入门槛。
- 高度可扩展。整个调用链追踪通路都应该可扩展,以应对不断接入的服务。
- 实时数据采集。全链路追踪系统从数据采集、分析、查询,到展示整个链路的操作都要尽量快速,这样才能完成对线上问题的快速定位。
- 提供决策支持。全链路追踪系统可以定位业务系统问题,通过分析系统服务,为服务的优化提供决策支持。
通过上面列出的设计目标可知,全链路追踪系统的主要功能如下:
- 对调用请求进行整个链路追踪,分析每个环节的耗时,并协助开发和运维人员找到性能瓶颈。
- 展示调用服务之间的拓扑关系。
- 对线上服务进行监控与报警。
- 采用简单的接入方式,和业务代码低耦合。
- 实时采集数据,可以设置采集率。
- 可以展示调用链的 UI 页面。
基本概念
不同的开源链路追踪系统的设计虽然不同,但基本上都包括 Trace、Span、Tag 及采样率等几部分。下面将讲解全链路追踪系统中的一些常用概念。1. Span
Span是调用链中的一个基本单元。通常,一次服务调用会创建一个 Span,每个 Span 都有一个 ID 来标识,并且它在调用链中是唯一的。同时,Span 中还有其他信息,如描述信息、Tag 信息及父 Span id 等。如图 1 所示为一个 Span 链路信息图。如果 Span 没有父 Span,则它是根 Span。通过 Span id 与 Parent id 可以查询整个链路中的Span。同时,每个 Span 都封装了很多信息,如操作描述信息、时间戳信息及键值对(Tag)信息。

图1 Span链路图
2. Trace
通常,一个调用链会生成一条 Trace,由唯一的 Trace id 来标识。一条 Trace 可以由一个或多个 Span 组成,类似于树状结构,是一条调用链路,相当于一次完整的请求链路。如图 2 所示,一条链路只有一个 Trace id,每个 Span 就是链路中的节点,节点之间的连线使 Span 与父节点 Span 发生联系,每个 Span中保存了一些请求信息。

图2 Trace链路图
3. Tag
Tag 用来描述 Span 中的一些特殊信息。在调用链的过程中,开发者如果需要保存一些特殊的业务信息,可以通过 Tag 设置键值对的方式进行保存。4. 采样率
线上环境对性能要求很高,如果对全部的请求都开启链路信息采集,会有一定的压力,因此可以通过设置采样率,在不牺牲大量性能的情况下进行信息采集,或者在某些关键时刻进行采集,便于定位线上问题。采样率可以设置全采样或某个速度进行采集。开源的全链路追踪系统
全链路追踪系统已经是大型互联网应用程序的必备中间件,被广泛应用于监控系统或调用链追踪系统。现在有很多的开源全链路追踪系统供大家使用。下面我们讲解从开源的全链路追踪系统架构等方面介绍比较知名的调用链追踪工具。Dapper简介
Dapper 是谷歌公司内部的调用链追踪系统,该系统没有开源。谷歌公司在 2010 年发表了论文 Dapper, a Large-Scale Distributed Systems Tracing Infrastructure,其中定义了追踪数据的格式、追踪方式及调用链追踪系统的架构等理论模型。大部分开源调用链追踪系统都是参照 Dapper 这篇论文提出的模型进行实现的。
如图 3 所示为 Dapper 收集数据的过程。Dapper 对谷歌公司内部的通用框架都提供了装配工具,服务部署了这些装配工具后就会对调用链进行追踪,装配工具将追踪信息保存到机器的磁盘上,每台服务器上部署的 Dapper daemon 会将追踪信息收集到 Dapper Collector上。
Dapper Collector 根据各个服务上报的追踪信息中包含的 traceId、spanId 和 parentSpanId 组装成完整的调用链,同时注明每个环节的耗时,然后进行存储并提供查询功能。

图3 Dapper架构图
Zipkin简介
Zipkin 是 Twitter 公司按照 Dapper 论文中定义的追踪数据格式、追踪方式和架构进行了开发实现。Zipkin 主要包括 Collector、Storage和UI界面等组件,同时提供数据查询功能,如图 4 所示。
图4 Zipkin架构图
Zipkin 的整个架构与 Dapper 非常类似,它装配了追踪工具的服务:
- 首先将追踪信息上报给 Transport;
- 然后 Collector 对追踪信息进行处理、存储;
- 最后前端UI通过调用API查询存储中的信息并进行展示。
其中,Transport 支持 HTTP、Kafka 等,Storage 存储支持 MySQL、Elasticsearch 和 Cassandra 等。Zipkin 的追踪是独立于开发语言的,只要满足 Zipkin 的追踪数据格式即可,它支持的框架包括 Grpc、Spring Web、Spring Boot 及 Spring Cloud 等。
Pinpoint简介
Pinpoint 是韩国的搜索公司 Naver 基于 Google Dapper 开发的一款开源分布式调用链追踪系统。Pinpoint 对代码零侵入,运用了 Java Agent 字节码增强技术,只需要添加启动参数即可使用。如图 5 所示,Pinpoint 框架的基本组成部分与 Zipkin 相似:
- Pinpoint Collector 作为收集组件,收集各种性能数据;
- Pinpoint Agent和服务一起运行,作为探针采集数据;
- Pinpoint Web UI是展示页面;
- HBase Storage作为存储组件,将采集到的数据存到HBase中。

图5 Pinpoint架构图
Pinpoint 使用字节码增强技术对服务进行埋点,追踪信息通过 Thrift 等方式上传到 Pinpoint Collector, Pinpoint 负责计算统计指标,并将实时结果和原始追踪信息都存入 HBase,前端 Web UI 从 HBase 中读数据进行展示查询。
Pinpoint 支持追踪的服务包括 Spring Boot、Thrift 和 Dubbo 等。它采用字节码增强技术侵入服务,业务无须修改代码,具有实时统计展示、JVM 实时监控及调用链追踪服务的特点。
Skywalking简介
Skywalking 是国内开源的一款调用链追踪系统。2019 年 4 月 17 日,SkyWalking 成为 Apache 的顶级项目,当前支持的开发语言包括Java、.NET 和 Node.js 等,数据存储支持 MySQL 和 Elasticsearch 等。Skywalking 跟 Pinpoint 一样,采用字节码注入的方式实现代码的无侵入,支持云原生,目前增长势头强劲,其架构如图 6 所示。

图6 Skywalking架构图
Skywalking 在逻辑上包含 4 部分,分别是:
- Probes:主要用于收集和格式化数据;
- Platform backend:支持数据聚合、分析和处理;
- Storage:用于数据存储,支持MySQL、H2和ElasticSearch等;
- Web UI:用于数据的可视化。
开源的全链路追踪系统比较
开源的全链路追踪系统从架构上看包括以下几个方面。1. 采集方式
采集方式就是通常所说的埋点。埋点是调用链追踪系统与业务服务交互的部分,该部分需要做到低消耗与低侵入。Pinpoint 与 Skywalking开源组件采用了字节码增强技术,可以做到低侵入。追踪数据的上传有两种方式,即 HTTP 和 TCP。此外,也可以通过日志采集方式进行追踪。Skywalking 的采集对吞吐量的影响比较小。
2. 数据计算
根据上传的追踪数据可以统计多维度指标,以了解服务的各种状态,如实时的 QPS、调用延时、延时分布、服务状态监控及服务依赖关系拓扑图等。3. 数据存储
原始数据量比较大,一般存储在 HDFS、HBase、Elasticsearch 和 Cassandra 等分布式数据库中。统计报表类数据的数据量比较小,需要具有快速地按时间检索的能力,一般存储在 MySQL 或时序数据库中。4. 数据展示
调用链追踪系统的数据最终通过UI界面展示,其中包含许多查询指标和调用链树形展示。Pinpoint界面的展示效果更加丰富,Zipkin的拓扑局限于服务与服务之间。Zipkin实践
Spring Boot 2.x 提供了集成 Zipkin 的工具包,开发者可以很容易地在自己的业务工程里集成 Zipkin。下面介绍一下简单的集成示例。(1)根据要求下载 zipkin-server 的 JAR 包,然后在本地启动 Zipkin 的 Server 实例,启动命令如下:
Java –jar zipkin-server.jar
(2)访问 http://localhost:9411/zipkin,即可打开 Zipkin 的 Web UI 页面,如图 7 所示。
图7 Zipkin主页面
(3)为本地服务添加 Zipkin 的相关依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> <version>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin</artifactId> <version>2.2.3.RELEASE</version> </dependency>(4)在本地服务配置文件中添加 Zipkin 配置信息:
spring:
zipkin:
enabled: true
baseUrl: http://127.0.0.1:9411
sleuth:
sampler:
probability: 1

图8 查找Trace信息
(6)单击信息即可进入详情页面,如图 9 所示。

图9 Trace的详细信息
图 9 展示了一次请求中 Zipkin 统计的信息,包括响应时间、http.method、http.path、mvc.controller.class、mvc.controller.method、traceId、spanId 和 parentId 等。
Skywalking实践
Pinpoint 与 Skywalking 都是使用 Agent 进行采集,其原理都是字节码增强技术。接下来将介绍 Skywalking 与 Spring Boot 的集成示例。具体步骤如下:1) 下载 Skywalking 包
访问 https://www.apache.org/dyn/closer.cgi/skywalking/,选择 Skywalking 包,如果使用 Elasticsearch 7.x 版本,则需要下载相关的版本。本例选择不使用 Elasticsearch 包,版本是 8.0.1。下载并解压后,目录包含以下几个部分:
- bin目录:主要存放启动脚本,包含 oapService.sh 和 webappService.sh 等。
- config目录:oap 服务的配置,包含一个配置文件 application.yml。
- agent目录:Skywalking 的 Agent,一般用来采集业务系统的日志。
- webapp目录:Skywalking 前端的 UI 界面服务。
- 直接单击 bin 目录下的 startup.bat 或 startup.sh 文件,即可启动 oapService 和 Webapp 服务。
2) 为应用程序配置启动参数
添加 VM options 为:-javaagent:E:\\apache-skywalking-apm-8.0.1\\apache-skywalking-apm-bin\\agent\\skywalking-agent.jar;
将环境变量设置为
W_AGENT_NAME=skywalking-test
,然后启动本地服务,发送一次服务请求。3) 打开 Skywalking 后台的 UI 页面
- “仪表盘”页面可以监控到本地服务和当前端点;
- “拓扑图”页面用于展示调用的拓扑结构;
- “追踪”页面用于展示调用链的树状信息。

声明:《Java系列教程》为本站“54笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。