Tracing 是在上世纪 90 年代就已出现的技术,但真正让该领域流行起来的还是源于 Google 的一篇 Dapper 论文。分布式追踪系统发展很快,种类繁多,但无论哪种组件,其核心步骤一般有 3 步:代码埋点、数据存储和查询展示,如下图所示为链路追踪组件的组成。
链路追踪组件的组成
目前流行的链路追踪组件有 Jaeger、Zipkin、Skywalking 和 Pinpoint 等。在数据采集过程中,对用户代码的入侵和不同系统 API 的兼容性,导致切换链路追踪系统需要巨大的成本。
为了解决不同的分布式追踪系统 API 不兼容的问题,诞生了 OpenTracing 规范。OpenTracing 是一个轻量级的标准化层,它位于应用程序/类库和追踪或日志分析程序之间。OpenTracing 提供了 6 种语言的中立工具:Go、JavaScript、Java、Python、Objective-C 和 C ++。如下图所示为 OpenTracing 的架构。它支持 Zipkin、LightStep 和 Appdash 等追踪组件,并且可以轻松集成到开源的框架中,例如 gRPC、Flask、Django 和 Go-kit 等。
OpenTracing 架构
OpenTracing 是一个 Library 库,定义了一套通用的数据上报接口,要求各个分布式追踪系统都来实现这套接口。这样一来,应用程序只需要对接 OpenTracing,而无需关心后端采用的到底是什么分布式追踪系统,因此开发者可以无缝切换分布式追踪系统,也使得在通用代码库增加对分布式追踪的支持成为可能。
OpenTracing 于 2016 年 10 月加入 CNCF 基金会,是继 Kubernetes 和 Prometheus 之后,第三个加入 CNCF 的开源项目。它是一个中立的(厂商无关、平台无关)分布式追踪的 API 规范,提供统一接口,可方便开发者在自己的服务中集成一种或多种分布式追踪的实现。
在大家熟悉了分布式链路追踪中的一些基础概念之后,我们来具体了解一下这几种流行的分布式链路追踪组件。
Zipkin 是一款分布式链路追踪组件,由 Twitter 开源,同样也兼容 OpenTracing API:它基于 Google Dapper 的论文设计,国内外很多公司都在用,文档资料也很丰富,其架构如下图所示。
Zipkin 架构图(来源 Zipkin 官网)
从 Zipkin 的架构图可知,Zipkin 包含如下 4 个部分:
Zipkin 分布式链路监控的优势是语言无关性,整体实现较为简单。Zipkin 支持 Java、PHP、Go 和 NodeJS 等语言客户端。社区支持的插件较为丰富,包括 RabbitMQ、Mysql 和 HTTPClient 等(具体参见 https://github.com/openzipkin/brave/tree/master/instrumentation)。Zipkin UI 界面功能较为简单,本身无告警功能,可能需要二次开发。
Jaeger 是 CNCF 云原生项目之一,Jaeger 受 Dapper 和 OpenZipkin 的启发,由 Uber 开源的分布式追踪系统,兼容 Open Tracing API。它用于微服务的监控和排查,支持分布式上下文传播、分布式事务的监控、报错分析、服务的调用网络分析以及性能/延迟优化。Jaeger 的服务端使用 Go 语言实现,其存储支持 Cassandra、Elasticsearch 和内存,并提供了 Go、Java、Node、Python 和 C++ 等语言的客户端库。Jaeger 具有如下的特性:
Jaeger 的架构如下图所示。
Jaeger 架构图
我们来分析一下 Jaeger 的架构图,Jaeger 主要由以下几部分组成:
下图为 Jaeger UI 中的统计视图,还可以点击进去查看请求的链路调用详情。
Jaeger 链路监控页面
列表中展示了请求的追踪记录,每次请求的时间、涉及的服务名和 Span 数量。通过统计的散列图,可以很清楚地看到请求的响应时间分布。相比于 Zipkin,Jaeger 在界面上较为丰富,但是也无告警功能。
SkyWalking 是一个国产的 APM 开源组件,具有监控、跟踪和诊断云原生架构中分布式系统的功能。SkyWalking 支持多个来源和多种格式收集 Trace 和 Metric 数据,包括:
SkyWalking 的核心是数据分析和度量结果的存储平台,通过 HTTP 或 gRPC 方式向 SkyWalking Collecter 提交分析和度量数据。SkyWalking Collecter 对数据进行分析和聚合,并存储到数据库。最后我们可以通过 SkyWalking UI 的可视化界面对最终的结果进行查看。SkyWalking 支持从多个来源和多种格式收集数据:多种语言的 Skywalking Agent、Zipkin v1/v2、Istio 勘测、Envoy 度量等数据格式。
如下图所示为 SkyWalking 6.x 的架构图。SkyWalking 整体架构的模块较多,但是结构比较清晰,主要就是通过收集各种格式的数据进行存储,然后展示。
SkyWalking 6.x 架构图
SkyWalking 支持的存储组件有:ES、H2、Mysql、TiDB 和 Sharding Sphere。SkyWalking 的 UI 界面提供的链路追踪查询较为简单,SkyWalking 拥有非常活跃的中文社区,支持多种语言的探针,且对国产开源软件全面支持。SkyWalking 在探针性能方面表现优异,根据官方提供的基准测试结果,SkyWalking 探针的性能损耗较低。
Pinpoint 是一个 APM 工具,适用于用 Java/PHP 编写的大型分布式系统,Go 语言项目不能直接应用 Pinpoint,如需使用则需要使用代理进行改造。这里简单进行介绍,因为其链路追踪的分析较为完善。Pinpoint 也是受 Dapper 的启发,可以通过跟踪分布式应用程序之间的调用链,帮助分析系统的整体结构以及它们中的组件是如何相互连接,如下图所示。
Pinpoint 链路监控页面
Pinpoint 的追踪数据粒度非常细,用户界面功能强大,Pinpoint 中的服务调用展示做得非常丰富,在这方面它优于市面上大多数组件。Pinpoint 使用 HBase 作为存储带 来了海量存储的能力。丰富的数据背后,必然需要大量的数据采集,因此在几款常用链路追踪组件中,Pinpoint 的探针性能最低,在生产环境需要注意应用服务的采样率,过高会影响系统的吞吐量。
另外,Pinpoint 目前仅支持 Java 和 PHP 语言,采用字节码增强方式去埋点,所以在埋点时不需要修改业务代码,是非侵入式的,非常适合项目已经完成之后再增加调用链监控的实践场景。Pinpoint 并不支持除 Java、PHP 语言之外的探针,在 Go 语言项目中应用需要基于 Pinpoint 进行二次封装开发。
如上几个小节对 4 种当前流行的链路追踪组件进行了简单介绍,我们对每个组件的组成和特性有了大概的了解,下面我们将根据如下的几个指标对它们进行直观的对比。
指标/组件 | Zipkin | Jaeger | Skywalking | Pinpoint |
---|---|---|---|---|
OpenTracing 兼容 | 支持 | 支持 | 支持 | 不支持 |
客户端支持语言 | Java、C#、Go、PHP 等 | Java、C#、Go、PHP 等 | Java, .NET Core, NodeJS and PHP | Java、PHP |
传输协议 | Http/MQ | UDP/Http | gRPC | Thrift |
Web UI | 弱 | 一般 | 一般 | 强 |
扩展性 | 强 | 强 | 一般 | 弱 |
性能损失 | 一般 | 一般 | 低 | 高 |
实现方式 | 拦截请求,侵入 | 拦截请求,侵入 | 字节码注入,无侵入 | 字节码注入,无侵入 |
告警 | 不支持 | 不支持 | 支持 | 支持 |
可以看出,Zipkin 和 Jaeger 在各个方面都差不多,Jaeger 是在 Zipkin 的基础上改进了 Web UI 和传输协议等方面且支持更多的客户端语言。SkyWalking 相对前面两种组件来说,功能较为齐全,探针性能损耗低,同时也支持多种语言的客户端。Pinpoint 在 Web UI 的丰富性上完胜其他三种,然而其不支持 Go 语言客户端,实际应用需要进行改造,除此之外性能和可扩展性方面的不足值得我们在选型时考虑权衡。每种组件都有其优势和劣势,笔者建议在链路追踪组件的选型时,根据自身业务系统的实际情况,哪些不能妥协,哪些可以舍弃,从而更好的选择一款最适合的组件。
当然,除了通过修改应用程序代码增加分布式追踪之外,还有一种不需要修改代码的非入侵的方式,那就是 Service Mesh。Service Mesh 在网络层面拦截,通过 Sidecar(Sidecar 主张以额外的容器来扩展或增强主容器,而这个额外的容器被称为 Sidecar 容器)的方式为各个微服务增加一层代理,通过这层网络代理来实现一些服务治理的功能,因为是工作在网络层面,可以做到跨语言、非入侵。
本文主要介绍了分布式链路追踪的 OpenTracing 规范,以及几种常见的分布式链路追踪组件选型。通过在 Go 语言中通过修改应用程序代码增加分布式追踪。这种方式有一定的侵入性,但也是目前使用最多的分布式链路追踪方式。接下来的内容我们将进入实践环节,通过一个案例演示如何应用 Zipkin 来追踪微服务请求的细节。
学完本课时,关于分布式链路追踪的选型,你觉得哪一款分布式链路追踪组件适合你的业务场景,欢迎你在留言区和我分享。