本文为2022.10.29存稿
链路追踪(Traces)
为什么需要?
在分布式系统,尤其是微服务系统中,一次外部请求往往需要内部多个模块,多个中间件,多台机器的相互调用才能完成。在这一系列的调用中,可能有些是串行的,而有些是并行的。在这种情况下,我们如何才能确定这整个请求调用了哪些应用?哪些模块?哪些节点?以及它们的先后顺序和各部分的性能如何呢?
起源
建立在2010年Google的一篇Dapper论文的基础上,这篇论文可以说是指明了链路追踪设计的指导方针和设计原则
OpenTracing
OpenTracing通过提供平台无关、厂商无关的API,使得开发人员能够方便的添加(或更换)追踪系统的实现。 OpenTracing提供了用于运营支撑系统的和针对特定平台的辅助程序库。
在 OpenTracing API 中,有三个主要对象:
- Tracer
- Span
- SpanContext
Trace
Trace 是一个有向非循环图,那么 Trace 有且只有一个起点。这个起点会创建一个 Tracer 对象,这个对象一开始初始化了 trace id 和 process,trace id 是一个 32 个长度的字符串组成,它是一个时间戳,而 process 是起点进程所在主机的信息。
Span
Span 基本结构前面提到 Span 通俗概念:一个操作,它代表系统中一个逻辑运行单元。Span 之间通过嵌套或者顺序排列建立因果关系。Span 包含以下对象:
- Name : 名称,这个名称简单并具有可读性高。如:一个 RPC 方法的名称,一个函数名,或者一个大型计算过程中的子任务或阶段;
- 起始时间和结束时间:操作的生命周期;
- Attributes: 属性,一组<K,V>键值对构成的集合。值可以是字符串、布尔或者数字类型,一些链路追踪系统也称为 Tags;
- Event:事件;
- SpanContext: Span 上下文内容;
- Links:描述 Span 节点关系的连线,它的描述信息保存在 SpanContext 中;
Span之间的关系可以包含两种:
ChildOf
: Span A 是 Span B 的孩子,即"ChildOf"关系FollowsFrom
: Span A 是 Span B 的父级,即"FollowsFrom"关系
SpanContext
SpanContext作用是在一个 Trace 中,把当前 Span 和 Trace 相关信息传递到下级 Span 。它的基本结构类似<Trace_id, Span_id, sampled> ,每个 SpanContext 包含以下基本属性:
- TraceId:随机 16 字节数组。比如 4bf92f3577b34da6a3ce929d0e0e4736
- SpanId:随机 8 字节数组。比如 00f067aa0ba902b7
- Baggage Items :一个键值对集合,也需要 Span 间传输。
关系
一个Trace (链路追踪过程)是多个 Span 操作组成的一个有向无环图(DAG),每一个 Span 代表 Trace 中被命名并计时的连续性的执行片段。
为了把调用链状态在 Span 中传递下去,期望最终保存下来,比如打入日志、保存到数据库。SpanContext 会封装一个键值对集合,然后将数据像行李一样打包,这个打包的行李在 OpenTelemetry 称为 Baggage(背包) 。
OpenTelemetry
OpenTelemetry 是 CNCF 的一个可观测性项目,旨在提供可观测性领域的标准化方案,解决观测数据的数据模型、采集、处理、导出等的标准化问题,提供与三方 vendor 无关的服务。
OpenTelemetry 是由两个开源项目合并组成的:
- OpenCensus
- 面向 trace 和 metrics 进行数据模型标准化,并提供采集、处理、导出的工具
- OpenTracing
- 面向 trace 进行数据模型标准化,并提供采集、处理、导出的工具
2019 年 5 月,两个开源项目合并,官方宣布开源 OpenTelemetry 项目。
仓库
链路追踪组件分析
近年来,出现了 APM 系统,APM 称为应用程序性能管理系统,可以进行软件性能监视和性能分析。APM 是一种Metrics,但是现在有融合 Tracing 的趋势(2021)
APM系统(应用性能管理 or 应用性能监控)
application performance managerment
application performance monitoring
APM | 厂商 | OpenTracing | 语言支持 | 其他 |
---|---|---|---|---|
Jeager | Uber | 兼容 | 支持Go等 | 后端组件均开放 Prometheus 监控 zap日志标准输出 |
Skywalking | Huawei | 兼容 | 支持Go,Java,.NET Core, NodeJS and PHP 等 | 模块较多,但是结构清晰,就是通过收集数据进行存储、展示 |
Zipkin | 兼容 | 支持 Java、PHP、Go and NodeJS 等 | UI 界面功能简单,无告警功能,需要二次开发 |
CNCF生态
分析
Jaeger
架构
两种部署方式(一种含有kafka用作初步缓存)
- Jaeger-Client 是由 OpenTracing API 封装成编程语言的 SDK。
- Jaeger-Agent 是一个监听在 UDP 端口上接收 span 数据的网络守护进程,它会将数据批量发送给 collector。
- Jaeger-Collector 负责处理四面八方推送来的跟踪信息,然后存储到后端,可以存储到 ES 等数据库中。
- Jaeger-Query/UI 从数据库中请求数据,可以让用户在界面上看到这些被分析出来的跟踪信息。