4. 指标定义与建模:从黄金指标到 Prometheus 数据模型

聊到失效预警,第一个绕不开的问题就是:你到底要监控什么?

很多人一上来就堆指标,CPU、内存、磁盘、网络……全拉上。结果告警一响,全是噪音。我见过最夸张的项目,一天能收到两千条告警,运维团队直接选择“静默”——这其实比没监控更危险。

所以这一章,我们得把指标这件事彻底理清楚。从最经典的黄金指标,到自定义业务指标,再到怎么管好这些指标的“元数据”,最后落到 Prometheus 的数据模型上。嗯,一步步来。

4.1 黄金指标:四个维度看透系统

Google 的 SRE 团队总结过四个黄金指标——延迟、流量、错误、饱和度。说白了,这四个维度能覆盖绝大多数系统的健康状态。我个人习惯,不管接什么新系统,先拿这四个维度去套一遍,基本不会漏掉关键点。

指标 核心含义 常见度量方式 我踩过的坑
延迟 (Latency) 请求从发出到收到响应的时间 P50 / P95 / P99 分位延迟 只看平均值会掩盖长尾问题
流量 (Traffic) 系统承载的请求量级 QPS / RPS / 带宽 流量突降也可能是故障(比如上游熔断)
错误 (Errors) 请求失败的比率 HTTP 5xx / 业务错误码 / 超时 显式错误 + 隐式错误(如返回 200 但内容为空)都要算
饱和度 (Saturation) 系统资源被消耗的程度 CPU 使用率 / 内存占用 / 队列深度 饱和度到 100% 才告警往往已经晚了

核心原则:黄金指标不是让你四个都抓,而是让你先问自己——这个系统如果出问题,用户最先感知到的是哪个维度?从那里开始。

举个例子。我在维护一个支付网关时,延迟 P99 从 200ms 涨到 2s,但平均延迟才 300ms。如果只看平均值,你根本不会发现异常。但用户已经在骂了。所以记住:延迟一定要看分位值,P99 比平均值真实得多。

4.2 自定义业务指标:把监控和钱挂钩

黄金指标能告诉你系统“活着”,但没法告诉你业务“赚不赚钱”。

我曾经帮一家电商公司做失效预警,技术指标全绿,但老板发现订单量在跌。为什么?因为下单接口返回了 200,但数据库写入失败了——这叫“静默错误”。

所以,你必须定义业务指标。比如:

  • 订单成功率:下单请求中最终支付成功的比例
  • 核心链路耗时:从点击“购买”到看到“支付成功”页面的总时长
  • 用户登录失败率:连续 5 分钟内登录失败的次数占比

我的建议:业务指标不要超过 10 个。每多一个指标,就多一份维护成本和告警噪音。挑最核心的 3-5 个,盯死它们。

定义业务指标时,有个容易忽略的点:指标口径要统一。比如“订单成功率”,研发和运营的理解可能不一样。研发觉得“接口返回 200 就算成功”,运营觉得“用户付了钱才算成功”。我建议在指标元数据里明确写清楚计算逻辑,避免后续扯皮。

4.3 指标元数据管理:给指标上“身份证”

指标一多,管理就乱。你想想看,一个 Prometheus 实例里可能跑着几千个指标,三个月后你还能记得每个指标是干嘛的吗?

所以我们需要指标元数据。说白了,就是给每个指标配一张“身份证”。

元数据字段 说明 示例
指标名称 唯一标识 http_request_duration_seconds
指标类型 Counter / Gauge / Histogram / Summary Histogram
所属域 业务 / 中间件 / 基础设施 中间件
计算口径 指标的计算逻辑说明 统计所有 HTTP 请求从接收到响应的时间
告警阈值 建议的告警触发条件 P99 > 1s 持续 5 分钟
负责人 谁对这个指标负责 @张三

注意:元数据管理不是一次性工作。指标变更(比如口径调整、阈值修改)一定要同步更新元数据。我曾经因为没更新口径,导致两个团队对同一个指标的理解完全相反,排查了三天才发现问题。

实践中,我习惯把指标元数据存在一个 YAML 文件里,纳入 Git 管理。每次修改都走 PR 评审,这样既有记录,又能追溯。

4.4 Prometheus 数据模型:理解底层存储逻辑

聊完指标定义,我们得看看 Prometheus 到底怎么存这些数据的。理解了数据模型,你写 PromQL 的时候才不会懵。

Prometheus 的数据模型核心就一句话:时序数据 = 指标名 + 标签集合 + 时间戳 + 样本值。

举个例子:

http_requests_total{method="GET", endpoint="/api/users", status="200"} 1024 @ 1700000000

这个序列表示:在时间戳 1700000000 时,GET 请求 /api/users 返回 200 的次数是 1024。

这里有几个关键点:

  • 指标名:描述“是什么”,比如 http_requests_total
  • 标签:描述“哪个维度”,比如 method、endpoint、status
  • 时间戳:精确到毫秒
  • 样本值:一个 float64 数值

为什么标签这么重要?因为 Prometheus 的查询、聚合、告警,全是靠标签来筛选的。你想想看,如果没有 method 标签,你怎么单独看 POST 请求的延迟?

设计原则:标签的基数(即不同取值的数量)要控制。比如 user_id 这种取值几百万的标签,千万别加到指标里——Prometheus 会直接撑爆。我见过有人把 ip 当标签,结果一个指标产生了上亿条时间序列,查询直接超时。

Prometheus 支持四种指标类型:

类型 特点 适用场景
Counter 只增不减(重启会重置) 请求总数、错误总数
Gauge 可增可减 CPU 使用率、内存占用、在线人数
Histogram 分桶统计,可计算分位值 请求延迟、响应大小
Summary 类似 Histogram,但分位值由客户端计算 需要精确分位值且能接受客户端开销

我个人更推荐用 Histogram 而不是 Summary。为什么?因为 Summary 的分位值在客户端算好了,你没法在服务端做跨实例聚合。而 Histogram 的桶数据可以聚合,灵活性高得多。

4.5 本章知识体系图

下面这张图把指标定义与建模的核心逻辑串起来了。从黄金指标出发,到自定义业务指标,再到元数据管理,最后落到 Prometheus 数据模型——每一步都环环相扣。

指标定义与建模知识体系 指标定义与建模知识体系 黄金指标 自定义业务指标 指标元数据管理 Prometheus 数据模型 延迟 流量 错误 饱和度 订单成功率 / 核心链路耗时 用户登录失败率 / 支付转化率 名称 / 类型 / 所属域 计算口径 / 告警阈值 / 负责人 指标名 + 标签 + 时间戳 + 值 Counter / Gauge / Histogram / Summary 核心原则:标签基数控制 + 口径统一 + 元数据 Git 化管理 💡 实践建议 • 黄金指标先覆盖核心链路,再逐步扩展 • 业务指标不超过 10 个,盯死 3-5 个关键指标 • 元数据纳入 Git 管理,变更走 PR 评审

4.6 避坑指南:我踩过的三个坑

最后分享几个真实教训,希望能帮你少走弯路。

  1. 标签基数爆炸:我曾经把 request_id 作为标签,结果 Prometheus 内存直接打满。记住:标签的取值数量要可控,一般建议不超过 10 万。
  2. 指标口径不一致:两个团队对“错误率”的定义不同,一个算 5xx,一个算所有非 200。最后告警对不上,排查浪费了两天。解决方案:元数据里写清楚计算逻辑。
  3. Histogram 桶设置不合理:默认桶范围太宽,导致 P99 计算不准确。我后来改成 [0.1, 0.5, 1, 2, 5, 10] 秒,才真正反映出长尾问题。

一个小技巧:定义指标时,先问自己三个问题——这个指标能反映用户真实体验吗?它的标签基数可控吗?它的计算口径团队内统一吗?三个问题都回答“是”,再把它加进去。