系列目录
引子
现代分布式链路追踪公认的起源是 Google 在 2010 年发表的论文《Dapper : a Large-Scale Distributed Systems Tracing Infrastructure》,介绍了 Google 从 2004 年开始使用的分布式追踪系统 Dapper 的实现原理。此后,所有业界有名的追踪系统,无论是国外 Twitter 的Zipkin、Naver 的Pinpoint,抑或是国内阿里的鹰眼EagleEye、大众点评的CAT、个人开源的SkyWalking(后进入 Apache 基金会孵化毕业)都受到 Dapper 论文的直接影响。
广义上讲,一个完整的分布式追踪系统应该由数据收集、数据存储和数据展示三个相对独立的子系统构成,而狭义上讲的追踪则就只是特指链路追踪数据的收集部分。譬如Spring Cloud Sleuth就属于狭义的追踪系统,通常会搭配 Zipkin 作为数据展示,搭配 Elasticsearch 作为数据存储来组合使用,而前面提到的那些 Dapper 的徒子徒孙们大多都属于广义的追踪系统,广义的追踪系统又常被称为“APM 系统”(Application Performance Management)。本节我们讨论的是狭义上的链路追踪产品/协议。
一、发展史
文字无力,咱们直接上图:
如上图所示,市面上主流开源产品\协议都列出了。整体态势很清晰,主流产品Zipkin、SkyWalking、Jaeger都拥抱了CNCF-OpenTracing规范,最终并入了OpenTelemetry。笔者预言,整个微服务架构发展都在云原生化,不支持通用规范的产品很快就会泯灭在历史的车轮下。
二、原理概览
2.1 基本原理
为了有效地进行分布式追踪,Dapper 提出了“追踪”与“跨度”两个概念。
- 从客户端发起请求抵达系统的边界开始,记录请求流经的每一个服务,直到到向客户端返回响应为止,这整个过程就称为一次“追踪”(Trace)。
- 由于每次 Trace 都可能会调用数量不定、坐标不定的多个服务,为了能够记录具体调用了哪些服务,以及调用的顺序、开始时点、执行时长等信息,每次开始调用服务前都要先埋入一个调用记录,这个记录称为一个“跨度”(Span)。Span 的数据结构应该足够简单,以便于能放在日志或者网络协议的报文头里;也应该足够完备,起码应含有时间戳、起止时间、Trace 的 ID、当前 Span 的 ID、父 Span 的 ID 等能够满足追踪需要的信息。每一次 Trace 实际上都是由若干个有顺序、有层级关系的 Span 所组成一颗“追踪树”(Trace Tree),如下图所示。
从实现来看,为每次服务调用记录 Trace 和 Span,并以此构成追踪树结构,听着好像也不是很复杂,然而考虑到实际情况,追踪系统在功能性和非功能性上都有不小的挑战。功能上的挑战来源于服务的异构性,各个服务可能采用不同程序语言,服务间交互可能采用不同的网络协议,每兼容一种场景,都会增加功能实现方面的工作量。而非功能性的挑战具体就来源于以下这四个方面:
- 低性能损耗:分布式追踪不能对服务本身产生明显的性能负担。追踪的主要目的之一就是为了寻找性能缺陷,越慢的服务越是需要追踪,所以工作场景都是性能敏感的地方。
- 对应用透明:追踪系统通常是运维期才事后加入的系统,应该尽量以非侵入或者少侵入的方式来实现追踪,对开发人员做到透明化。
- 随应用扩缩:现代的分布式服务集群都有根据流量压力自动扩缩的能力,这要求当业务系统扩缩时,追踪系统也能自动跟随,不需要运维人员人工参与。
- 持续的监控:要求追踪系统必须能够 7x24 小时工作,否则就难以定位到系统偶尔抖动的行为。
2.2 主流实现
目前,追踪系统根据数据收集方式的差异,可分为三种主流的实现方式,分别是基于日志的追踪(Log-Based Tracing),基于服务的追踪(Service-Based Tracing)和基于边车代理的追踪(Sidecar-Based Tracing),笔者分别介绍如下:
- 基于日志的追踪的思路是将 Trace、Span 等信息直接输出到应用日志中,然后随着所有节点的日志归集过程汇聚到一起,再从全局日志信息中反推出完整的调用链拓扑关系。日志追踪对网络消息完全没有侵入性,对应用程序只有很少量的侵入性,对性能影响也非常低。缺点是异步时延和无法保证数据完整性。这也是不用ELK做tracing的原因。日志追踪的代表产品是 Spring Cloud Sleuth。
- 基于服务的追踪是目前最为常见的追踪实现方式,被 Zipkin、SkyWalking、Pinpoint 等主流追踪系统广泛采用。服务追踪的实现思路是通过某些手段给目标应用注入追踪探针(Probe),针对 Java 应用一般就是通过 Java Agent 注入的。探针在结构上可视为一个寄生在目标服务身上的小型微服务系统,它一般会有自己专用的服务注册、心跳检测等功能,有专门的数据收集协议,把从目标系统中监控得到的服务调用信息,通过另一次独立的 HTTP 或者 RPC 请求发送给追踪系统。因此,基于服务的追踪会比基于日志的追踪消耗更多的资源,也有更强的侵入性,换来的收益是追踪的精确性与稳定性都有所保证,不必再依靠日志归集来传输追踪数据。下面是一张 Pinpoint 的追踪效果截图,从图中可以看到参数、变量等相当详细方法级调用信息。
如上图所示,Pinpoint 这种详细程度的追踪对应用系统的性能压力是相当大的,一般仅在出错时开启,而且 Pinpoint 本身就是比较重负载的系统(运行它必须先维护一套 HBase),这严重制约了它的适用范围,目前服务追踪的其中一个发展趋势是轻量化,国产的 SkyWalking 正是这方面的佼佼者。另外值得一提的是,一款叫“博睿”的商业化产品,做得个人感觉比zikpin、pp还要好。做到了链路、详情、日志抓取、错误分析、代码栈、耗时一个地方搞定。如下图:
- 基于边车代理的追踪是服务网格的专属方案,也是最理想的分布式追踪模型,它对应用完全透明,无论是日志还是服务本身都不会有任何变化;它与程序语言无关,无论应用采用什么编程语言实现,只要它还是通过网络(HTTP 或者 gRPC)来访问服务就可以被追踪到;它有自己独立的数据通道,追踪数据通过控制平面进行上报,避免了追踪对程序通信或者日志归集的依赖和干扰,保证了最佳的精确性。如果要说这种追踪实现方式还有什么缺点的话,那就是服务网格现在还不够普及,未来随着云原生的发展,相信它会成为追踪系统的主流实现方式之一。还有就是边车代理本身的对应用透明的工作原理决定了它只能实现服务调用层面的追踪,像上面 Pinpoint 截图那样本地方法调用级别的追踪诊断是做不到的。
现在市场占有率最高的边车代理Envoy就提供了相对完善的追踪功能,但没有提供自己的界面端和存储端,所以 Envoy 和 Sleuth 一样都属于狭义的追踪系统,需要配合专门的 UI 与存储来使用,现在 SkyWalking、Zipkin、Jaeger、LightStep Tracing等系统都可以接受来自于 Envoy 的追踪数据,充当它的界面端。
如使用SpringCloud全家桶,未使用云原生框架,无脑上此方案即可:sleuth+zipkin=Spring Cloud Sleuth上报tracing数据->kafka->zipkin存储(Elasticsearch)+展示查询
三、 追踪规范化
几乎市面上所有的追踪系统都是以 Dapper 的论文为原型发展出来的,功能上差距不大。目前还没有像日志、度量那样出现具有明显统治力的产品,仍处于群雄混战的状态。为了推进追踪领域的产品的标准化,2016 年 11 月,CNCF 技术委员会接受了 OpenTracing 作为基金会第三个项目。OpenTracing 是一套与平台无关、与厂商无关、与语言无关的追踪协议规范,只要遵循 OpenTracing 规范,任何公司的追踪探针、存储、界面都可以随时切换,也可以相互搭配使用。操作层面,OpenTracing 只是制定了一个很薄的标准化层,位于应用程序与追踪系统之间,这样探针与追踪系统就可以不是同一个厂商的产品,只要它们都支持 OpenTracing 协议即可互相通讯。此外,OpenTracing 还规定了微服务之间发生调用时,应该如何传递 Span 信息(OpenTracing Payload),以上这些都如下图所示:
2016年,OpenTracing 规范公布后,几乎所有业界有名的追踪系统,譬如 Zipkin、Jaeger、SkyWalking 等都很快宣布支持 OpenTracing。2019 年,OpenTracing 并入可观测性的终极解决方案OpenTelemetry。OpenTelemetry 野心颇大,不仅包括追踪规范,还包括日志和度量方面的规范、各种语言的 SDK、以及采集系统的参考实现,它距离一个完整的追踪与度量系统,仅仅是缺了界面端和指标预警这些会与用户直接接触的后端功能,OpenTelemetry 将它们留给具体产品去实现,勉强算是没有对一众 APM 厂商赶尽杀绝,留了一条活路。
OpenTelemetry 一诞生就带着无比炫目的光环,直接进入 CNCF 的孵化项目,它的目标是统一追踪、度量和日志三大领域(目前主要关注的是追踪和度量,日志方面,官方表示将放到下一阶段再去处理)。不过,OpenTelemetry 毕竟是 2019 年才出现的新生事物,尽管背景渊源深厚,前途光明,但未来究竟如何发展,能否打败现在已经有的众多成熟系统,目前仍然言之尚早。
=========参考==================
全文学习整理自凤凰架构:http://icyfenix.cn/distribution/observability/tracing.html
dapper论文:https://static.googleusercontent.com/media/research.google.com/zh-CN//archive/papers/dapper-2010-1.pdf
如果你觉得本文对你有点帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!