阈值怎么定 · 从拍脑袋到有依据

「CPU > 80% 告警」这种阈值从哪来?通常是拍的。这一章给出定阈值的四种正当方法(SLO 倒推、历史基线、容量推算、趋势预测)、静态阈值的三个失效场景,以及一套可执行的决策流程。

作者 David更新于 第 33 篇(共 52 篇)

阈值怎么定 · 从拍脑袋到有依据

“CPU > 80% 就告警”——这个 80% 从哪来的?

诚实的答案通常是:某个人某天拍的,然后被抄了五年。这一章讲怎么定出有依据的阈值。

静态阈值为什么经常失效

“某指标 > 某常数”这种静态阈值,在三种场景下必然失效:

① 规模变了,阈值没变

第 2 部分讲过的磁盘例子:disk_used > 85% 在 100GB 盘上意味着“还剩 15GB,可能几小时”,在 10TB 盘上意味着“还剩 1.5TB,能撑一周”。同一个阈值,紧迫性差几个数量级。

② 业务有周期,阈值没有

qps < 100 告警(检测流量异常)在白天是合理的,在凌晨 4 点会每天准时误报一次。业务天然有昼夜、工作日/周末、大促的周期,而常数没有。

③ 阈值定在“能承受”而非“该承受”

最隐蔽的一种:P99 < 2s 这个阈值,可能只是因为“我们现在就是 1.8s”。它记录的是现状,不是目标——于是系统慢慢劣化到 1.9s,你也不会知道,因为告警没响。阈值变成了对现状的追认。

四种正当的定法

① 从 SLO 倒推(最正统)

业务承诺: "下单成功率 99.9%"
  ↓
错误预算: 0.1%
  ↓
告警阈值: 错误率 > 0.1%(或更精细:用[燃烧率](/manual/observability/slo-burn-rate))

阈值来自承诺,不是来自现状。 这是唯一“正确”的方法——第 2 部分反复强调过。

② 从历史基线推(最实用)

# 过去 7 天,这个指标的 P99 通常是多少?
quantile_over_time(0.99, service:http_latency:p99[7d:5m])

先测量,再定阈值。 定在“比正常情况明显差、但还没到用户抱怨”的位置。注意:这个方法只能告诉你“什么是不寻常”,不能告诉你“什么是不可接受”——那得靠 SLO。两者要对齐(对不上时才是真问题)。

③ 从容量推(资源类)

压测得知: 单实例 500 QPS 时 P99 开始劣化
  ↓
留 30% 余量: 350 QPS 告警

这适合有明确容量拐点的资源。前提是你真的压测过——没压测过就是在猜。

④ 用趋势预测(增长类)

# 按当前速度,4 小时内磁盘会满
predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[6h], 4*3600) < 0

这是静态阈值的正确替代品:它告警的不是“现在多满”,而是“还有多久出事”——后者才是你真正关心的,而且它自动适应盘的大小。

predict_linear 是个被低估的函数:任何“会持续增长直到撞墙”的东西(磁盘、证书有效期、配额、Kafka lag)都该用它,而不是百分比阈值。

症状 vs 原因:该对哪个告警

这是告警设计里最重要的一条原则:

优先对症状**(用户能感知的)告警,而不是对原因(内部状态)告警。**

类型例子该 page 吗
症状错误率 > 1%、P99 > 1s、服务不可达✅ 该叫醒人
原因CPU > 80%、内存 > 90%、连接池满❌ 通常不该

为什么?

  • 原因告警会漏 —— 你不可能列全所有可能的原因。CPU 正常、内存正常、磁盘正常,但服务就是挂了(比如死锁、下游炸了)。第 0 部分讲的“未知的未知”——基于原因的告警只能覆盖“已知的未知”。
  • 原因告警会吵 —— CPU 90% 但用户毫无感知?那可能只是资源被充分利用。你半夜爬起来,发现啥事没有。
  • 症状告警不会漏 —— 不管什么原因,只要用户受影响,症状必然变化。一条 SLO 告警,覆盖了所有你没想到的故障模式。

那“原因”类指标有什么用? 用来排障,不是用来 page。它们该在看板上、在排障手册里,而不是在电话里。

例外:有预测性的饱和度可以告警——但应该是低优先级(ticket 而非 page):“磁盘 4 小时后会满”值得开个工单白天处理,不值得半夜叫人。第 2 部分说饱和度是唯一有预测性的信号,这就是它的正确用法。

分级:不是所有告警都该叫醒人

一条告警最重要的属性不是阈值,而是“它响了之后,人要做什么”。

severity含义判据渠道
page立刻叫醒人用户正在受影响,且需要人立刻介入电话 / 短信
ticket工作时间处理有问题但能等(如磁盘 4 小时后满)工单
info只记录有参考价值,不需要行动看板 / 日志

判据是一个尖锐的问题:“如果这条告警在凌晨 3 点响,我会起床吗?如果不会,它凭什么是 page?”

每条 page 级告警都该能回答三个问题:

  1. 用户在受影响吗? —— 不是的话,不该 page。
  2. 需要人立刻做点什么吗? —— 如果系统能自愈(重试、failover),不该 page。
  3. 有 runbook 吗? —— 被叫醒的人知道该干嘛吗?没有 runbook 的 page = 把一个人叫醒然后让他从零开始猜。

三个都是“是”,才配当 page。 这个筛子能滤掉大多数团队 80% 的告警——下一章会讲为什么这么狠是对的。

低流量的陷阱(以及解法)

第 2 部分提过的问题:深夜只有 2 个请求,错了 1 个 = 50% 错误率 → 告警炸响。但这可能毫无意义。

解法一:比率 + 绝对量双条件

(service:http_errors:ratio_rate5m > 0.01)
and
(service:http_errors:rate5m > 0.1)      # 每秒至少 0.1 个错误才算数

解法二:用更长的窗口 —— [30m] 而非 [5m],让样本量够。

解法三(最优):用 SLO 燃烧率 —— 它天然处理这个问题,因为它衡量的是“错误预算消耗的速度”,而低流量时消耗本来就慢。下一章讲。

决策流程

图表加载中…

小结与下一章

静态阈值三种必然失效:规模变了阈值没变(磁盘百分比)、业务有周期而常数没有(凌晨误报)、阈值定在“能承受”而非“该承受”(变成对现状的追认)。四种正当定法:① SLO 倒推(阈值来自承诺不是现状,最正统);② 历史基线(先测量再定,但它只能说“什么不寻常”、不能说“什么不可接受”);③ 容量推算(要真压测过);④ 趋势预测(predict_linear 是静态阈值的正确替代——告警“还有多久出事”而非“现在多满”,且自动适应规模)。最重要的原则:对症状告警,不对原因告警——原因会漏(覆盖不了未知的未知)、会吵(CPU 高但用户无感);症状不会漏(一条 SLO 告警覆盖所有没想到的故障模式);原因类指标用来排障不用来 page。分级判据是“凌晨 3 点会起床吗”,page 必须满足用户在受影响 + 需要人立刻介入 + 有 runbook。低流量陷阱用双条件 / 长窗口 / 燃烧率解。

有没有一种方法,能把“阈值”这个问题从根上解决?有——下一章。👉 SLO 与燃烧率告警。

参考资料

  • [1] Google《SRE Book》第 6 章(症状 vs 原因)、《SRE Workbook》第 5 章(Alerting on SLOs)。
  • [2] Prometheus 官方文档:predict_linear()、Alerting rules;Rob Ewaschuk「My Philosophy on Alerting」。
  • [3] 关联常见指标范围、饱和度的预测性、USE。

本页目录