一粟 · yisu.app
· 14 min read
可观测

微服务可观测性的三大支柱

三大支柱不是「全都要」的清单,而是要按业务场景裁剪。本文用一次完整的链路故障排查过程,说明什么时候看指标、什么时候翻日志、什么时候拉 trace。

为什么有「三大支柱」这回事

「Metrics、Logs、Traces」这个提法来自 Peter Bourgon 和 Cindy Sridharan 在 2017 年前后整理的论文。它解决了一个具体问题:在分布式系统下,「发生了什么」和「为什么发生」需要不同维度的信号。

  • Metrics:高度聚合、低成本、能跨时间维度看趋势。
  • Logs:原始、详细、不可丢失。
  • Traces:结构化、跨服务、解释「调用路径」。

三者各自不同维度,没有冲突,能互补。

Metrics:数字信号

指标是「系统状态的量化值」。常见类型:

类型例子使用
Counter请求数累计计数
Gauge当前连接数瞬时值
Histogram延迟分位数
SummaryP99客户端聚合

指标最适合回答「系统现在 OK 吗」「过去 30 分钟涨了多少」。它不能告诉你「这次失败为什么」。

Logs:原始信号

日志记录「这个时刻发生了什么」。日志的好处是「保留了上下文」。代价是:写入压力大、查询慢、不容易聚合。我们一年处理 200 TB 日志,查询延迟通常 5–30 秒。

日志不是越详细越好。它们应该被设计成「能回答某个具体问题」的颗粒度。

Traces:关系信号

我在另一篇关于 Trace 的文章里专门讲过。但这里想强调:trace 不是「日志的替代」,而是一种新的视角。它最擅长的不是「日志很长」,而是「告诉你这些日志属于同一次请求」。这是故障定位时的「金钥匙」。

三大支柱的取舍矩阵

不同场景对它们的依赖差异很大。我的默认推荐:

  • 告警 → 指标(Counter / Histogram)
  • 事故还原 → Trace + Log
  • 容量规划 → Metric + Service Mesh 数据
  • 慢请求归因 → Trace 优先 + Metric 分组
  • 代码层 bug → Log(带 trace_id)

一次真实的「分布式排查」

下面是某次事故的复盘。看我们是如何用这三个支柱把问题定位到行级的:

  1. 告警:调用 B 服务的 P99 突增到 1.8s(Metric Histogram)。
  2. 看 trace:根据告警时间窗拉取 trace,定位到 B 服务的 status update 节点耗时 1.5s。
  3. 看 metric:B 服务慢节点的 DB latency 平稳,排除数据库;B 服务的 Redis 调用计数上升。
  4. 拉日志:在 trace_id 关联的日志中,发现大量 SET key value EX 600 NX 失败。
  5. 根因:该段代码在 NX 失败时进入重试循环,循环次数被某种边界条件放大。
  6. 修复:加幂等 + 上限 + 重试间隔避让。

可以看到:metric 给出异常、trace 给出路径、log 给出原因。三者缺一不可。

它们之间的「关联键」

三大支柱想要有效联动,必须有「关联键」。最常用的是 trace_id。具体做法:

  • 请求进入网关时生成 trace_id。
  • 所有调用都透传 trace_id,包括 MQ、HTTP、DB。
  • 日志里打 trace_id=...
  • 指标里打 trace_count 维度(按 trace_id 维度聚合指标)。

成本与采样

三大支柱的建设成本差异很大:

支柱成本优化关键
Metric采样率、标签维度
Log落盘策略、冷热分层
Trace中高采样策略、属性数量

对成本敏感的小团队,可以从「Metric 全量 + Log 抽样 + Trace 头部 1%」起步,再逐步扩展。

把 OpenTelemetry 当成「统一胶水」

未来 2–3 年最值得投入的是 OpenTelemetry。它不是后端,但是自动从代码侧采集三大信号并把它们送到各自的后端。我们的系统迁移到 OTel SDK 后,三大支柱的接入成本下降了一半。

几条非技术但很关键的事

  • 三大支柱选型一定不要被「指标数量」「日志总量」迷惑,要看它们的「查询体验」。
  • 让任何一次事故复盘都能查到对应的 trace_id。
  • 把数据保留策略写成配置:Metric 180 天,Log 7 天原始 + 90 天归档,Trace 7 天原始。

三大支柱不是工程师的负担,而是工程师对系统的「认知工具」。做好它们,再复杂的系统也讲得清楚。

按团队规模选择技术栈

不同规模的团队对三大支柱的选型差异很大。经验是:

团队规模MetricLogTrace
小(<10 人)Prometheus轻量 LokiJaeger
中(10–50)Prometheus + ThanosELKJaeger + OTel
大(>50)Mimir / CortexOpenSearchOTel + 商业方案

选型不是「越新越好」,而是「与团队人力匹配」。

把它们放在一张「故障定位剧本」里

我把事故定位流程标准化为 5 步:

  1. 看 Metric,确认异常范围和严重度。
  2. 拉 Trace,找异常调用路径。
  3. 对每个 Span 看相关 Metric 看细节。
  4. 查 Log(按 trace_id 索引),找到出错上下文。
  5. 把结论整理为 Runbook 的一节。

这是 PDCA 在故障响应里的具体落地:先观察,再定位,最后改进。每完成一次,这套剧本都会更稳定,团队的判断也会更快。