4. 黄金信号与四大指标:延迟、流量、错误、饱和度

Google SRE 在《SRE 工作手册》中提出的“黄金信号”(The Four Golden Signals)是面向用户与系统健康度的最核心可观测维度。任何 Metric 设计都应优先覆盖这四个象限:延迟(Latency)、流量(Traffic)、错误(Errors)、饱和度(Saturation)。本章通过具体实例,展示如何为每个信号设计可落地的 Metric。

4.1 四大信号定义与设计原则

信号 核心关注点 典型 Metric 示例 设计陷阱
延迟(Latency) 请求处理耗时,区分成功与失败请求的延迟 p50/p99/p999 响应时间(ms) 仅用平均值掩盖长尾;未排除失败请求的虚假低延迟
流量(Traffic) 系统承载的请求量级与速率 QPS、RPS、带宽(bps)、活跃连接数 忽略流量季节性模式;未按路由/用户分片
错误(Errors) 显式错误(HTTP 5xx)与隐式错误(业务失败) 错误率(%)、错误计数、错误码分布 只统计显式错误;忽略超时导致的隐式失败
饱和度(Saturation) 资源使用程度与排队压力 CPU 利用率、内存使用率、队列深度、连接池占用 仅看利用率均值;未定义“饱和阈值”
设计原则:每个黄金信号至少应包含 1 个计数型 + 1 个分布型 Metric。例如延迟同时上报 Histogram(分布)和 Counter(总耗时),错误同时上报 Counter(计数)和 Gauge(当前错误率)。

4.2 延迟(Latency)Metric 设计实例

延迟是用户体验最直接的反映。设计时需区分成功请求延迟与失败请求延迟,避免将超时失败的低延迟混入成功样本。

# Prometheus 示例:HTTP 请求延迟 Histogram
http_request_duration_seconds_bucket{le="0.005", status="2xx"} 1200
http_request_duration_seconds_bucket{le="0.01", status="2xx"} 3400
http_request_duration_seconds_bucket{le="0.05", status="2xx"} 8900
http_request_duration_seconds_bucket{le="0.1", status="2xx"} 9500
http_request_duration_seconds_bucket{le="+Inf", status="2xx"} 10000
http_request_duration_seconds_count{status="2xx"} 10000
http_request_duration_seconds_sum{status="2xx"} 452.3
  • 分位数计算:使用 histogram_quantile(0.99, ...) 得到 p99 延迟。
  • 按端点拆分:增加 endpoint 标签区分 /api/login 与 /api/search。
  • 失败请求单独上报:使用 status="5xx" 或 status="error" 标签,避免污染成功延迟分布。
常见错误:只上报平均延迟(avg)。平均延迟会完全掩盖 1% 请求耗时 10s 的长尾问题。必须使用分位数(p50/p99/p999)或直方图。

4.3 流量(Traffic)Metric 设计实例

流量反映系统当前负载压力,用于容量规划与异常检测。设计时需区分入口流量与出口流量,并按服务/路由/用户维度打标。

# 入口流量:每秒请求数(QPS)
# 使用 Rate 函数计算
rate(http_requests_total{service="checkout"}[1m])

# 出口流量:下游 RPC 调用量
rate(rpc_calls_total{service="checkout", downstream="payment"}[1m])

# 带宽流量:网络层字节数
rate(node_network_transmit_bytes_total{device="eth0"}[1m])
流量类型 典型 Metric 标签建议
HTTP 请求 http_requests_total method, endpoint, status, service
消息队列 kafka_messages_in_total topic, partition, consumer_group
数据库查询 db_queries_total db_instance, query_type, table
用户会话 active_users_gauge region, tier, device_type

4.4 错误(Errors)Metric 设计实例

错误信号需覆盖显式错误(HTTP 5xx、RPC 异常)与隐式错误(业务返回错误码、超时未响应)。设计时建议使用错误预算(Error Budget)概念。

# 显式错误率:HTTP 5xx 占比
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))

# 隐式错误:业务错误码计数
rate(business_errors_total{error_code="INSUFFICIENT_FUNDS"}[1m])

# 错误预算:SLO 为 99.9%,每月允许 0.1% 错误
error_budget_remaining = 1 - (total_errors / total_requests) / (1 - 0.999)
关键设计点:
  • 错误 Metric 必须包含 error_code 或 status 标签,便于快速定位错误类型。
  • 对于超时导致的隐式错误,建议单独上报 timeout_errors_total,不要混入正常请求计数。
  • 错误率报警应使用 滑动窗口(如 5 分钟),避免瞬时抖动触发告警风暴。

4.5 饱和度(Saturation)Metric 设计实例

饱和度衡量资源接近极限的程度。设计时需定义饱和阈值,并关注排队长度而非仅利用率。

# CPU 饱和度:使用利用率 + 运行队列长度
node_cpu_seconds_total{mode="idle"}  # 计算利用率
node_load1  # 1 分钟平均运行队列

# 内存饱和度:实际使用量 vs 限制
container_memory_working_set_bytes / container_spec_memory_limit_bytes

# 连接池饱和度:活跃连接数 / 最大连接数
db_connections_active / db_connections_max

# 磁盘 I/O 饱和度:I/O 等待时间占比
rate(node_disk_io_time_seconds_total[1m]) / rate(node_disk_io_time_seconds_total[1m] + rate(node_disk_io_time_weighted_seconds_total[1m])
资源类型 利用率 Metric 饱和度 Metric(排队/等待)
CPU CPU 利用率(%) 运行队列长度(load average)
内存 内存使用率(%) OOM 事件计数、swap 使用量
磁盘 磁盘使用率(%) I/O 等待时间、磁盘队列深度
网络 带宽利用率(%) 丢包率、TCP 重传率
连接池 连接使用率(%) 连接等待队列长度、超时拒绝计数

4.6 黄金信号关联分析:故障特征提取

单一信号往往无法定位根因,需要将四个信号交叉关联。以下 SVG 展示了典型故障场景下黄金信号的联动模式。

黄金信号关联分析:典型故障特征模式 模式 1:流量突增 • 流量:⬆️ 陡升 • 延迟:⬆️ 缓慢上升 • 错误:⬆️ 少量增加 • 饱和度:⬆️ 资源吃紧 根因:促销活动/爬虫 模式 2:代码缺陷 • 流量:➡️ 不变 • 延迟:⬆️ 突增 • 错误:⬆️ 陡升 • 饱和度:⬆️ 缓慢上升 根因:新发布版本 bug 模式 3:资源耗尽 • 流量:➡️ 不变 • 延迟:⬆️ 陡升 • 错误:⬆️ 超时错误 • 饱和度:⬆️ 达到 100% 根因:连接池/磁盘满 故障特征提取:多信号交叉验证 • 流量不变 + 延迟陡升 + 错误陡升 → 优先排查代码缺陷(模式 2) • 流量陡升 + 延迟缓慢上升 + 饱和度上升 → 优先排查容量/限流(模式 1) 黄金信号 Metric 设计检查清单 ✅ 延迟:是否区分成功/失败?是否使用分位数? ✅ 流量:是否按服务/端点拆分?是否使用 Rate 函数? ✅ 错误:是否覆盖显式+隐式错误?是否有错误预算? ✅ 饱和度:是否定义饱和阈值?是否监控排队长度?

4.7 黄金信号 Metric 设计总结

  • 延迟:使用 Histogram/Summary,按状态码和端点拆分,关注 p99 而非 avg。
  • 流量:使用 Counter + Rate,按服务/路由/用户分片,关注季节性模式。
  • 错误:使用 Counter + 错误码标签,区分显式与隐式错误,建立错误预算。
  • 饱和度:使用 Gauge + 利用率/排队长度,定义饱和阈值,优先监控排队指标。
最佳实践:每个服务至少暴露 4 个黄金信号相关的 Metric 组。在仪表盘中将四个信号放在同一时间轴,便于故障时快速交叉对比。报警规则应基于信号组合而非单一指标,例如“延迟 p99 > 1s 且错误率 > 5%”比单独报警更精准。