几款符合 OpenTracing 规范的分布式链路追踪组件介绍与选型 - 腾讯云开发者社区

腾讯云 · · 1786 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

分布式链路追踪组件是在分布式架构中很重要的组件,用于排查分布式系统所遇到的问题。市面上有多款流行的分布式链路追踪组件,包括 Zipkin、Jaeger、Pinpoint 和 Skywalking 等,我们来了解下这几款组件的相关特性,以帮助我们选型。

分布式链路追踪规范:OpenTracing

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 规范,提供统一接口,可方便开发者在自己的服务中集成一种或多种分布式追踪的实现。

几种流行的分布式链路追踪组件

在大家熟悉了分布式链路追踪中的一些基础概念之后,我们来具体了解一下这几种流行的分布式链路追踪组件。

简单易上手的 Twitter Zipkin

Zipkin 是一款分布式链路追踪组件,由 Twitter 开源,同样也兼容 OpenTracing API:它基于 Google Dapper 的论文设计,国内外很多公司都在用,文档资料也很丰富,其架构如下图所示。

Zipkin 架构图(来源 Zipkin 官网)

从 Zipkin 的架构图可知,Zipkin 包含如下 4 个部分:

  • Collector:存储和索引报上来的链路数据,以供后续查找。
  • Storage:Zipkin 的存储是可插拔的,最初是为了在 Cassandra 上存储数据而构建。除了 Cassandra,Zipkin 还原生支持 ElasticSearch 和 MySQL。
  • Zipkin Query Service(API):一旦数据被存储和索引,我们就需要一种方法来查看它。Zipkin 搜索提供了一个简单的 JSON API,用于查找和检索 Trace 记录。此 API 的主要使用者是 Web UI。
  • Web UI:Zipkin 查询链路追踪的界面。Web UI 提供了一种基于服务、时间和注解查看 Trace 记录的方法。

Zipkin 分布式链路监控的优势是语言无关性,整体实现较为简单。Zipkin 支持 Java、PHP、Go 和 NodeJS 等语言客户端。社区支持的插件较为丰富,包括 RabbitMQ、Mysql 和 HTTPClient 等(具体参见 https://github.com/openzipkin/brave/tree/master/instrumentation)。Zipkin UI 界面功能较为简单,本身无告警功能,可能需要二次开发。

云原生链路监控组件 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 主要由以下几部分组成:

  • 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 UI 中的统计视图,还可以点击进去查看请求的链路调用详情。

Jaeger 链路监控页面

列表中展示了请求的追踪记录,每次请求的时间、涉及的服务名和 Span 数量。通过统计的散列图,可以很清楚地看到请求的响应时间分布。相比于 Zipkin,Jaeger 在界面上较为丰富,但是也无告警功能。

SkyWalking

SkyWalking 是一个国产的 APM 开源组件,具有监控、跟踪和诊断云原生架构中分布式系统的功能。SkyWalking 支持多个来源和多种格式收集 Trace 和 Metric 数据,包括:

  • Java、.NET Core、NodeJS 和 PHP 语言自动织入的 SkyWalking 格式
  • 手动织入的 Go 客户端 SkyWalking 格式
  • Istio 追踪的格式
  • Zipkin v1/v2 格式
  • Jaeger gRPC 格式

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

Pinpoint 是一个 APM 工具,适用于用 Java/PHP 编写的大型分布式系统,Go 语言项目不能直接应用 Pinpoint,如需使用则需要使用代理进行改造。这里简单进行介绍,因为其链路追踪的分析较为完善。Pinpoint 也是受 Dapper 的启发,可以通过跟踪分布式应用程序之间的调用链,帮助分析系统的整体结构以及它们中的组件是如何相互连接,如下图所示。

Pinpoint 链路监控页面

Pinpoint 的追踪数据粒度非常细,用户界面功能强大,Pinpoint 中的服务调用展示做得非常丰富,在这方面它优于市面上大多数组件。Pinpoint 使用 HBase 作为存储带 来了海量存储的能力。丰富的数据背后,必然需要大量的数据采集,因此在几款常用链路追踪组件中,Pinpoint 的探针性能最低,在生产环境需要注意应用服务的采样率,过高会影响系统的吞吐量。

另外,Pinpoint 目前仅支持 Java 和 PHP 语言,采用字节码增强方式去埋点,所以在埋点时不需要修改业务代码,是非侵入式的,非常适合项目已经完成之后再增加调用链监控的实践场景。Pinpoint 并不支持除 Java、PHP 语言之外的探针,在 Go 语言项目中应用需要基于 Pinpoint 进行二次封装开发。

4 种分布式链路追踪组件的指标对比

如上几个小节对 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 来追踪微服务请求的细节。

学完本课时,关于分布式链路追踪的选型,你觉得哪一款分布式链路追踪组件适合你的业务场景,欢迎你在留言区和我分享。

1786 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传