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 分钟 |
设计要点:四大信号必须同时采集,缺一不可。仅监控延迟而忽略饱和度,可能在资源耗尽前无法预警;仅监控错误而忽略流量,可能错过慢速故障。
下图展示了四大黄金信号在服务调用链中的覆盖范围:
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 注册表,所有新指标必须经过评审才能上线。注册表包含:指标全名、类型、维度列表、单位、负责人、创建日期。这能有效防止重复指标和命名冲突。
下图展示了从命名规范到告警规则的整体链路:
3.4 小结:Metric 设计检查清单
在开始编写告警规则之前,请对照以下清单检查你的 Metric 设计:
- 四大信号是否完整? 每个服务至少包含延迟、流量、错误、饱和度各一个指标。
- 维度是否满足下钻需求? 至少包含 service、env、method、status_code 四个基础维度。
- 维度基数是否可控? 所有维度值的组合数不超过 10 万(对于 Prometheus 等 TSDB)。
- 命名是否符合规范? 采用 namespace.subsystem.metric.unit 结构,全部小写。
- 单位是否明确? 所有指标后缀标注单位(seconds/bytes/percent/count)。
- 是否有重复指标? 检查 Metric 注册表,避免团队内重复定义。
工程建议:将上述检查清单集成到 CI/CD 流水线中,每次新增 Metric 时自动校验。不符合规范的指标直接拒绝合并,从源头保证数据质量。