3. Metric Design 基础:四大黄金信号与维度规范

可观测性工程中,Metric(指标)是告警系统的核心数据源。设计不当的 Metric 会导致告警风暴、误报频发、根因定位困难。本节从 Google SRE 提出的四大黄金信号出发,结合维度设计与命名规范,建立一套可复用的 Metric 设计框架。

3.1 四大黄金信号

Google SRE 在《Site Reliability Engineering》中定义了四个核心信号,覆盖服务健康度的所有关键维度:

黄金信号 定义 典型指标示例 告警触发场景
延迟(Latency) 请求从发出到收到响应所消耗的时间 p50/p90/p99 响应时间 p99 延迟超过 500ms 持续 5 分钟
流量(Traffic) 系统承载的请求量或数据量 QPS、RPS、吞吐量(MB/s) QPS 突增 300% 或突降 80%
错误(Errors) 请求失败的比率或数量 HTTP 5xx 率、异常计数、超时率 错误率超过 1% 持续 3 分钟
饱和度(Saturation) 系统资源被使用的程度 CPU 使用率、内存使用率、连接池占用 CPU 使用率超过 90% 持续 10 分钟
设计要点:四大信号必须同时采集,缺一不可。仅监控延迟而忽略饱和度,可能在资源耗尽前无法预警;仅监控错误而忽略流量,可能错过慢速故障。

下图展示了四大黄金信号在服务调用链中的覆盖范围:

四大黄金信号覆盖模型 目标服务 延迟 (Latency) 流量 (Traffic) 错误 (Errors) 饱和度 (Saturation) 每个信号独立采集,但告警分析时需交叉关联:高延迟 + 低错误率 = 慢速故障;高饱和度 + 高错误率 = 资源瓶颈

3.2 Metrics 的维度设计原则

维度(Dimension)是附加在 Metric 上的标签,用于区分不同来源、不同属性的数据。合理的维度设计能大幅提升告警的精确度,避免因聚合过度导致的误报。

3.2.1 维度设计三原则

原则 说明 正确示例 错误示例
有限基数 维度值的数量应控制在可枚举范围内,避免无限增长 service_name, region, status_code user_id, request_id, session_id
可过滤性 每个维度应支持独立过滤和聚合,便于下钻分析 env=prod, method=POST combined_label="prod_POST"
稳定性 维度值在服务生命周期内不应频繁变化 version=v2.1.0 pod_name=web-abc123(每次重启变化)
常见陷阱:将高基数维度(如 user_id、trace_id)直接作为 Metric 标签,会导致时序数据库存储膨胀、查询性能下降,甚至引发告警系统 OOM。高基数数据应通过日志或 Tracing 系统处理,而非 Metrics。

3.2.2 推荐维度清单

以下维度适用于大多数微服务场景,建议作为标准模板:

  • 服务标识:service_name、service_version、instance_id
  • 环境与部署:env(prod/staging/dev)、region(us-east-1/cn-north-1)、az(可用区)
  • 请求属性:method(GET/POST/PUT)、endpoint(/api/v1/order)、status_code(2xx/4xx/5xx)
  • 资源属性:db_name、queue_name、cache_cluster

3.3 Metrics 的命名规范

统一的命名规范是团队协作和自动化处理的基础。混乱的命名会导致告警规则难以维护、仪表盘无法复用。

3.3.1 命名结构

推荐采用 层级命名法,以点号分隔,从左到右范围由大到小:

<namespace>.<subsystem>.<metric_name>.<unit>

示例:

app.order.http.requests_total.count
app.order.http.request_duration.seconds
infra.mysql.connection_pool.usage.percent
infra.cache.redis.hit_ratio.ratio

3.3.2 命名规则清单

规则 要求 正确 错误
1. 小写字母 全部使用小写字母 http_requests_total HttpRequestsTotal
2. 下划线分隔 单词间使用下划线 request_duration requestDuration
3. 单位后缀 明确标注单位(seconds/bytes/percent) memory_usage.bytes memory_usage
4. 类型后缀 计数器加 _total,直方图加 _bucket requests_total requests
5. 避免缩写 除非是公认缩写(http/db/cpu) connection_pool conn_pl

3.3.3 命名规范示例

以下是一个完整的 Metric 定义示例(Prometheus 格式):

# HELP app_order_http_requests_total Total number of HTTP requests
# TYPE app_order_http_requests_total counter
app_order_http_requests_total{method="POST",endpoint="/api/v1/order",status="200"} 1024

# HELP app_order_http_request_duration_seconds HTTP request latency
# TYPE app_order_http_request_duration_seconds histogram
app_order_http_request_duration_seconds_bucket{method="POST",le="0.1"} 512
app_order_http_request_duration_seconds_bucket{method="POST",le="0.5"} 890
app_order_http_request_duration_seconds_bucket{method="POST",le="1.0"} 980
app_order_http_request_duration_seconds_bucket{method="POST",le="+Inf"} 1024
app_order_http_request_duration_seconds_sum 320.5
app_order_http_request_duration_seconds_count 1024
最佳实践:在团队内建立 Metric 注册表,所有新指标必须经过评审才能上线。注册表包含:指标全名、类型、维度列表、单位、负责人、创建日期。这能有效防止重复指标和命名冲突。

下图展示了从命名规范到告警规则的整体链路:

Metric 设计到告警链路 命名规范 app.order.* 维度设计 method, endpoint, status 四大信号 延迟/流量/错误/饱和度 告警规则 p99 > 500ms 告警降噪的关键:命名规范 + 维度设计 + 黄金信号 三者缺一不可 命名混乱 → 告警规则难以编写;维度缺失 → 无法下钻定位;信号不全 → 漏报或误报

3.4 小结:Metric 设计检查清单

在开始编写告警规则之前,请对照以下清单检查你的 Metric 设计:

  1. 四大信号是否完整? 每个服务至少包含延迟、流量、错误、饱和度各一个指标。
  2. 维度是否满足下钻需求? 至少包含 service、env、method、status_code 四个基础维度。
  3. 维度基数是否可控? 所有维度值的组合数不超过 10 万(对于 Prometheus 等 TSDB)。
  4. 命名是否符合规范? 采用 namespace.subsystem.metric.unit 结构,全部小写。
  5. 单位是否明确? 所有指标后缀标注单位(seconds/bytes/percent/count)。
  6. 是否有重复指标? 检查 Metric 注册表,避免团队内重复定义。
工程建议:将上述检查清单集成到 CI/CD 流水线中,每次新增 Metric 时自动校验。不符合规范的指标直接拒绝合并,从源头保证数据质量。