4. Metric Design方法论

Google SRE 实践提炼出的四个黄金信号——延迟(Latency)、流量(Traffic)、错误(Errors)、饱和度(Saturation)——是构建可观测性度量的基石。在 SLO 台账设计中,黄金信号并非简单的指标罗列,而是需要转化为可量化、可告警、可归因的度量基线。本章将逐一拆解每个信号在 SLO 设计中的具体映射方法。

4.1 黄金信号四象限模型

四个信号分别从不同维度描述系统健康状态,组合使用可以覆盖绝大多数故障场景。下表总结了每个信号在 SLO 设计中的核心关注点与典型度量方式:

黄金信号 核心关注点 SLO 度量示例 典型数据源
延迟 请求处理速度是否满足用户预期 P99 延迟 ≤ 200ms APM、服务端耗时直方图
流量 系统承载的请求量级与趋势 QPS 容量水位 ≤ 80% 负载均衡器、网关指标
错误 请求失败的比例与类型 错误率 ≤ 0.1% HTTP 状态码、业务错误码
饱和度 资源耗尽前的剩余容量 CPU 使用率 ≤ 75% 基础设施监控、资源配额
设计原则:四个信号应同时纳入 SLO 台账,但权重不同。延迟和错误通常作为用户可见性指标,流量和饱和度作为容量预警指标。单一信号告警可能漏过复合故障。

4.2 延迟(Latency)——用户体验的标尺

延迟度量的是请求从发出到收到完整响应的时间。在 SLO 设计中,延迟不是平均值,而是高百分位值(P99、P95、P50)。平均值会掩盖长尾请求对用户体验的伤害。

  • P99 延迟 SLO:99% 的请求在阈值内完成。例如“P99 ≤ 200ms”意味着每 100 个请求中最多 1 个超过 200ms。
  • 分桶直方图:使用 Prometheus 直方图或 OpenTelemetry 直方图记录延迟分布,避免只存平均值。
  • 客户端 vs 服务端:优先使用客户端感知的延迟(真实用户体验),服务端延迟仅作为辅助。
# Prometheus 延迟直方图示例(单位:秒)
http_request_duration_seconds_bucket{le="0.1"} 1024
http_request_duration_seconds_bucket{le="0.2"} 2048
http_request_duration_seconds_bucket{le="0.5"} 3072
http_request_duration_seconds_bucket{le="1.0"} 3584
http_request_duration_seconds_bucket{le="+Inf"} 4096
http_request_duration_seconds_count 4096
http_request_duration_seconds_sum 512.0
常见陷阱:仅监控服务端处理时间,忽略网络延迟、客户端渲染时间、DNS 解析时间。SLO 台账中的延迟应尽量贴近用户真实感知,必要时引入合成监控(Synthetic Monitoring)补充。

4.3 流量(Traffic)——系统负载的晴雨表

流量反映系统当前承受的请求压力。在 SLO 设计中,流量本身不是目标,而是用于容量规划和异常检测的上下文信号。

  • QPS / RPS:每秒请求数,按服务、接口、地域等维度拆分。
  • 吞吐量:每秒处理的数据量(如 MB/s),适用于流处理或存储系统。
  • 并发连接数:适用于网关、数据库连接池等有连接上限的系统。

流量 SLO 通常不直接作为用户承诺,而是作为内部容量告警。例如:当 QPS 达到预估容量的 80% 时触发预警,预留扩容时间。

4.4 错误(Errors)——故障的直接体现

错误率是 SLO 中最直观的指标。但错误定义需要精细:

错误类型 示例 SLO 处理方式
显式错误 HTTP 5xx、超时、连接拒绝 直接计入错误率
隐式错误 HTTP 200 但业务返回失败(如“余额不足”) 需业务层标记错误码
部分错误 批量接口中部分成功、部分失败 按失败条目比例折算
退化错误 降级返回缓存数据,功能不完整 建议计入错误率(功能降级即错误)
# 错误率计算示例(PromQL)
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
* 100
关键实践:错误率 SLO 必须区分有效请求和无效请求(如爬虫、恶意攻击)。建议在网关层或应用层过滤掉非用户流量,避免错误率被污染。

4.5 饱和度(Saturation)——容量危机的预警

饱和度衡量系统资源接近极限的程度。与延迟和错误不同,饱和度通常在故障发生前就给出信号,是预防性指标。

  • CPU 饱和度:CPU 使用率 + 运行队列长度(Load Average)。
  • 内存饱和度:内存使用率 + 交换分区使用量(Swap)。
  • 磁盘饱和度:磁盘 I/O 等待时间 + 队列深度。
  • 网络饱和度:带宽使用率 + 丢包率。
  • 连接池饱和度:数据库连接池、线程池的使用率。

饱和度 SLO 的阈值通常低于 100%,预留缓冲空间。例如:CPU 饱和度 ≤ 75%,磁盘 I/O 等待 ≤ 10ms。

4.6 黄金信号联动分析

单个信号可能产生误判,四个信号联动才能准确判断故障根因。下图展示了黄金信号在典型故障场景中的联动关系:

黄金信号联动分析图 延迟 ↑ 流量 ↑ 错误 ↑ 饱和度 ↑ 场景一:流量突增导致资源饱和 流量 ↑ → 饱和度 ↑ → 延迟 ↑ → 错误 ↑(资源耗尽后开始丢请求) 场景二:代码缺陷导致慢查询 延迟 ↑(慢查询)→ 连接池饱和度 ↑ → 错误 ↑(连接超时)→ 流量不变或略降 场景三:硬件故障(磁盘损坏) 饱和度 ↑(I/O 等待)→ 延迟 ↑ → 错误 ↑ → 流量可能下降(客户端重试)

4.7 黄金信号到 SLO 台账的映射流程

将黄金信号落地到 SLO 台账,建议遵循以下步骤:

  1. 识别关键用户旅程:确定哪些请求路径对用户体验最重要(如登录、下单、搜索)。
  2. 为每个旅程定义延迟和错误 SLO:基于用户期望和业务容忍度设定阈值。
  3. 关联流量和饱和度指标:为每个服务设定容量上限,作为内部告警线。
  4. 建立信号联动告警:单一信号触发不一定是故障,两个以上信号同时异常才升级。
  5. 定期校准基线:随着系统演进,黄金信号的阈值需要重新评估。
台账模板示例:在 SLO 台账中,每个服务至少包含 4 行记录(延迟、流量、错误、饱和度),每行记录当前基线、告警阈值、SLO 目标、最近 30 天合规率。四个信号共同构成服务的健康画像。

4.8 黄金信号在 SLO 台账中的呈现

下图展示了黄金信号在 SLO 台账中的结构化呈现方式,每个信号独立记录但统一展示:

SLO 台账黄金信号记录结构 服务名称 黄金信号 当前基线 告警阈值 SLO 目标 用户登录服务 延迟 P99 = 180ms P99 > 200ms P99 ≤ 200ms 用户登录服务 流量 QPS = 850 QPS > 1200 QPS ≤ 1500 用户登录服务 错误 0.05% > 0.1% ≤ 0.1% 用户登录服务 饱和度 CPU 62% CPU > 75% CPU ≤ 75% 台账使用说明 • 每个服务独立记录 4 行黄金信号,便于快速定位异常维度 • 告警阈值应低于 SLO 目标,预留响应时间(如目标 200ms,告警 180ms) • 饱和度作为容量预警,不直接计入用户 SLO,但影响长期可靠性

4.9 黄金信号设计避坑清单

  • 不要只选一个信号:延迟正常不代表没有错误(如返回错误码但速度快),错误率低不代表系统不饱和。
  • 不要忽略隐式错误:业务层错误(如“商品已下架”)在 HTTP 层面可能是 200,但用户感知为失败。
  • 不要用平均值代替百分位:平均值会掩盖长尾延迟,P99 才能反映真实用户体验。
  • 不要将饱和度阈值设得太高:CPU 100% 时系统已经严重排队,应提前在 70%-80% 告警。
  • 不要忘记流量季节性:流量 SLO 基线应区分高峰/低谷时段,避免误告警。
最佳实践:在 SLO 台账中为每个黄金信号增加“趋势”列(上升/下降/平稳),帮助运维人员快速判断是突发故障还是缓慢劣化。趋势数据来自最近 1 小时与过去 7 天同一时段的对比。