4. Metric Design 方法论:黄金信号在 SLO 设计中的应用
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 黄金信号联动分析
单个信号可能产生误判,四个信号联动才能准确判断故障根因。下图展示了黄金信号在典型故障场景中的联动关系:
4.7 黄金信号到 SLO 台账的映射流程
将黄金信号落地到 SLO 台账,建议遵循以下步骤:
- 识别关键用户旅程:确定哪些请求路径对用户体验最重要(如登录、下单、搜索)。
- 为每个旅程定义延迟和错误 SLO:基于用户期望和业务容忍度设定阈值。
- 关联流量和饱和度指标:为每个服务设定容量上限,作为内部告警线。
- 建立信号联动告警:单一信号触发不一定是故障,两个以上信号同时异常才升级。
- 定期校准基线:随着系统演进,黄金信号的阈值需要重新评估。
台账模板示例:在 SLO 台账中,每个服务至少包含 4 行记录(延迟、流量、错误、饱和度),每行记录当前基线、告警阈值、SLO 目标、最近 30 天合规率。四个信号共同构成服务的健康画像。
4.8 黄金信号在 SLO 台账中的呈现
下图展示了黄金信号在 SLO 台账中的结构化呈现方式,每个信号独立记录但统一展示:
4.9 黄金信号设计避坑清单
- 不要只选一个信号:延迟正常不代表没有错误(如返回错误码但速度快),错误率低不代表系统不饱和。
- 不要忽略隐式错误:业务层错误(如“商品已下架”)在 HTTP 层面可能是 200,但用户感知为失败。
- 不要用平均值代替百分位:平均值会掩盖长尾延迟,P99 才能反映真实用户体验。
- 不要将饱和度阈值设得太高:CPU 100% 时系统已经严重排队,应提前在 70%-80% 告警。
- 不要忘记流量季节性:流量 SLO 基线应区分高峰/低谷时段,避免误告警。
最佳实践:在 SLO 台账中为每个黄金信号增加“趋势”列(上升/下降/平稳),帮助运维人员快速判断是突发故障还是缓慢劣化。趋势数据来自最近 1 小时与过去 7 天同一时段的对比。