最近给公司一个 MQ 轮子接上了 Tracing,发现我了解 Tracing 已经挺久了,但是并未归纳总结,形成知识体系,所以趁热打铁,整理下涉及的知识。
背景
为什么要有 Tracing
现在互联网基本已经把单体服务
拆分成多个微服务(MicroServices)
,基本上每个人手里面都得要有几个服务。在排查问题时会遇到一些很普遍的现象。例如一下几点:
- 工程师可能无法准确知道到底调用了哪些服务
- 工程师不可能对每个服务的内部都了如指掌
- 服务和服务器可能被许多不同的客户端调用
以上问题都会使调试和观察复杂系统变得很困难,迫切需要一套日志监控方案来以支持大规模、高复杂性的系统监控、排查、预警。
为此衍生出了一套日志监控方案,分类 3 类 Tracing、Logging、Metrics。
- Tracing
- 定义:任何可以绑定到系统中单个事务对象的生命周期的数据或元数据,它处理请求范围内的信息。
- 案例:想知道一个 API 请求调用了哪些服务,执行哪些操作。
- 项目:opentracing、skywalking
- Metrics
- 定义:在一段时间内组成单个逻辑指标、计数器或直方图的原子,有可聚合的特征。
- 案例:监控某个 API 一段时间时间的 QPS、RTT
- 项目:Prometheus,
- Logging
- 定义:应用程序调试或错误消息,有离散的特征。
- 案例:控制台快速输出日志
- 项目:zap、logrus
Tracing
Tracing 基本都是基于 Google 的 Dapper1 2 设计的。市面上大多数项目只是在社区、存储、上传等方式有一定区别。
OpenTracing
一个tracer过程中,各span的关系
[Span A] ←←←(the root span)
|
+------+------+
| |
[Span B] [Span C] ←←←(Span C 是 Span A 的孩子节点, ChildOf)
| |
[Span D] +---+-------+
| |
[Span E] [Span F] >>> [Span G] >>> [Span H]
↑
↑
↑
(Span G 在 Span F 后被调用, FollowsFrom)
Traces
一个 trace 代表一个潜在的,分布式的,存在并行数据或并行执行轨迹(潜在的分布式、并行)的系统。一个 trace 可以认为是多个 span 的有向无环图(DAG)。
Spans
一个 span 代表系统中具有开始时间和执行时长的逻辑运行单元。span 之间通过嵌套或者顺序排列建立逻辑因果关系。
Logs
每个 span 可以进行多次 Logs 操作,每一次 Logs 操作,都需要一个带时间戳的时间名称,以及可选的任意大小的存储结构。
Tags
每个 span 可以有多个键值对(key:value)形式的 Tags,Tags 是没有时间戳的,支持简单的对 span 进行注解和补充。
Jaeger
vs SkyWalking
业界比较出名的 Tracing 项目有 Jaeger3、SkyWalking4、Elastic APM 等。Skywalking 是 Java 写的最开始完全面向企业
功能 | Jaeger | SkyWalking |
---|---|---|
背景 | 属于 CNCF 基金会 | 属于 Apache 基金会 |
语言 | Go | Java |
社区 | 以 K8S 为主的云原生技术的标配 | 以 Java 为主的社区 |
GitHub Star | 13.4K | 16.8K |
数据存储 | ElasticSearch、Kafka、Cassandra、API | ElasticSearch |
接入 Tracing 需要考虑什么
Tracing 是一个基础设施,理论上企业所有的项目都会需要这样一个系统,可以快速的定位问题、监控指标。
- 接入后可以带来什么收益
- 接入需要投入什么成本, 什么时间做到什么程度
- 选择什么项目、基础设施包括但不限于
- Tracing 项目 Jaeger OR SkyWalking
- 基础设施怎么做, 自建 OR 云服务
- 怎么接入到框架 、 自研 OR 使用开源
我司以写 Go 为主,在 RPC、API、ORM 等一般的框架有造
OR包装
了轮子,而且大量使用阿里云
与Kubernetes
等云服务,最终选用将 Jaeger 与内部使用的依赖进行统一封装,用阿里云的服务进行存储。从结果上来看收益还是较大的。