想象你是一个家庭的“财务总管”,每月工资到账后,你要把生活费、房贷、储蓄一一规划好。但你还会特意留出一笔“可支配娱乐额度”——这笔钱允许偶尔吃顿大餐、买个小玩具,只要这个月不超支就行。如果月初不小心把玩具摔坏了要重买(突发故障),你就要提醒家人:这个月省着点,先别买新游戏了,等月底重新发工资再说。 这套家庭开支逻辑,恰恰就是 Google SRE 团队发明的错误预算(Error Budget)机制。系统的可用性就像“生活费收入”,我们不可能 100% 完美运行,就像你不会把每个月的钱全花光——总会预留一个“容错额度”(比如 99.9% 的 SLO 意味着 0.1% 的错误额度)。当故障把额度消耗殆尽,团队就进入“节省模式”:冻结新功能发布,优先修复稳定性,直到下个周期额度重置。 错误预算的价值在于:它把“稳定”和“创新”这两个看似对立的目标,统一到了一本账上。你不需要拍脑袋决定“这周能不能发版”,只需要看一眼账本——预算还有多少?花得有多快?一切用数字说话。下面,我们就翻开这本“家庭账本”,看看错误预算从起源到落地、从监控到决策的完整故事。

岗位关联

掌握错误预算,你就能用可量化指标驱动稳定与创新的平衡决策,让团队告别“拍脑袋冻结发布”,成为真正数据驱动的 SRE 工程师。

目录
  1. 可视化演示
  2. 预算起源:从 SRE 到错误预算
  3. 核心概念:SLO 与错误预算
  4. 消耗机制:预算如何被一点点花掉
  5. 燃烧率监控:给花钱速度装仪表盘
  6. 决策策略:超支时按下暂停键
  7. 团队协作:全家人一起管理账本
  8. 实践落地:从理论到工程落地
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示错误预算的核心机制,通过源头/管道/节点/终端四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

错误预算:错误预算 错误预算的核心概念与数学定义 错误预算消耗速率(Burn R 核心机制可视化 错误预算整体架构与关键组件

预算起源:从 SRE 到错误预算

从前有个家庭,每月收入一万元,但总有人想把钱花得一分不剩——今天换手机,明天买游戏,后天要旅游。可一旦家里水管爆了需要紧急维修,才发现钱全花光了。这个场景像极了传统运维团队:一边是老板催着上线新功能(创新),一边是用户抱怨服务不稳定(可用性),两边天天吵架,却没有一个统一的评判标准。

Google 的 SRE(Site Reliability Engineering,站点可靠性工程)团队也遇到过同样的问题。他们在 2016 年 SRE 手册中正式提出“错误预算”这个概念,核心思路是:把“稳定性”和“创新”都换算成同一个单位——预算。不要追求系统 100% 可用,因为那意味着你永远不敢发布新代码,就像为了省钱而天天吃泡面,日子反而过得更糟。

那怎么衡量可用性呢?传统上我们看“多少个九”。一个运行良好的服务通常用请求成功率来定义可用性,比如每 10000 个请求里只有 1 个失败,可用性就是 99.99%。这个定义是全队都认可的语言:

理解了可用性的度量方式后,你就明白为什么 SRE 团队要发明“错误预算”了——既然可用性不是 100%,那“缺失的那一块”就是一种天然存在的容错空间。与其假装它不存在,不如把它当成预算,光明正大地管理起来。就像那个家庭,与其假装永远不会出意外,不如每月留出一笔应急金。

可用性=1−失败请求数总请求数\displaystyle \text{可用性} = 1 - \frac{\text{失败请求数}}{\text{总请求数}}
这个公式是理解错误预算的起点:可用性不是拍脑袋定的“感觉挺稳”,而是由失败请求占比精确计算出的数字。100% 意味着零失败,在现实分布式系统中几乎不可能。
  1. 整体结构可用性等于 1 减去失败占比,即“好的部分 = 全部 - 坏的部分”。
    可用性=1−失败请求数总请求数\displaystyle \text{可用性} = 1 - \frac{\text{失败请求数}}{\text{总请求数}}
  2. 分子含义失败请求数,指在统计周期内返回错误状态(如 HTTP 5xx、超时)的请求数量。
    失败请求数\displaystyle \text{失败请求数}
  3. 分母含义总请求数,指同一周期内所有进入系统的请求总量,包括成功与失败。
    总请求数\displaystyle \text{总请求数}
  4. 整体运算用 1 减去失败占比,得到的就是“成功占比”,即系统可用性的量化值。
    1−失败请求数总请求数\displaystyle 1 - \dfrac{\text{失败请求数}}{\text{总请求数}}

核心概念:SLO 与错误预算

确定了“要留应急金”的思路后,接下来要回答的问题是:留多少?定得太严,等于没留,家人照样束手束脚;定得太松,应急金被挥霍一空,真出事时没钱修水管。SLO(Service Level Objective,服务级别目标)就是那个“留多少”的决定——比如“本月可用性必须达到 99.9%”,这句话翻译过来就是:我允许你有 0.1% 的错误空间。

这个 0.1% 就是错误预算。它像家庭账本里的“娱乐额度”:这个月你可以犯错、可以发布有风险的功能、可以踩点小故障,但总额度只有 0.1%。花完了,就得老老实实攒钱(修复稳定性),等下个月额度刷新再继续。

错误预算的公式简洁得令人意外——它就是 100% 减去 SLO:

这个公式揭示了错误预算的本质:它不是“系统坏了多少”,而是“我们允许它坏多少”。打个比方,父母不指望孩子每次都考 100 分,于是给了“允许错一道题”的额度——只要错题不超一道,就不必紧张。

有了这个额度,团队在开发新功能时就有了底气:只要预算还有,发布就是“合规”的;预算超了,任何人都可以叫停。这就是把“稳定性争论”变成“数字对账”的关键一步。

错误预算=1−SLO\displaystyle \text{错误预算} = 1 - \text{SLO}
SLO 是团队与用户之间的“可用性契约”。99.9% 的 SLO 自动产生 0.1% 的错误预算,这个预算就是团队每个月的“犯错空间”。
  1. SLO 符号SLO 是团队设定的服务可用性目标值,例如 0.999(即 99.9%)。
    SLO=0.999\displaystyle \text{SLO} = 0.999
  2. 整体减法用 1(100%)减去 SLO,得到允许失败的比例。
    1−SLO\displaystyle 1 - \text{SLO}
  3. 计算结果当 SLO 为 0.999 时,错误预算为 0.001,即 0.1%。
    1−0.999=0.001\displaystyle 1 - 0.999 = 0.001

消耗机制:预算如何被一点点花掉

错误预算像零花钱一样,是按月发放的。每个月 1 号,账本归零,重新获得一整个月的新鲜预算;这个月无论你怎么花、花多少,到下个月都不会累积。为什么按月而不是按年?因为如果按年结算,前 11 个月大手大脚,最后一个月才发现透支,为时已晚。按月刷新,让反馈周期短到可以及时纠偏。

那么 0.1% 的错误预算到底有多少“时间”?对于一个月 30 天、每天 24 小时、每小时 60 分钟的服务来说,它相当于:

这 43.2 分钟听起来不多,但要注意——它是累计值。一次大故障可能瞬间烧掉 20 分钟,剩下来 23 分钟预算就要精打细算了。这就是“消耗速率”概念的由来:花钱快慢(错误率)决定了预算能撑多久。

在真实监控中,我们不会等到月底才算总账,而是用滚动窗口(例如 28 天或 30 天文氏窗口)持续观察。想象你每天记账:今天花了 1 分钟预算,明天赚回 1 分钟额度(旧窗口滑出、新窗口滑入),账本始终反映最近一个月的消耗情况。这样既避免了月初冲动的挥霍,也能快速捕捉到异常消耗。

月度预算(分钟)=30×24×60×(1−SLO)\displaystyle \text{月度预算(分钟)} = 30 \times 24 \times 60 \times (1 - \text{SLO})
当 SLO = 99.9% 时,每月错误预算约 43.2 分钟。这 43.2 分钟是所有请求失败时间加起来的总额度——一旦累计系统不可用时间超过它,本月预算就烧完了。
  1. 月度秒数基础30 天 × 24 小时 × 60 分钟,先算出一个月总共有多少分钟。
    30×24×60=43200\displaystyle 30 \times 24 \times 60 = 43200
  2. 乘以预算比例用总分钟数乘以错误预算比例(1 - SLO)。
    43200×(1−0.999)\displaystyle 43200 \times (1 - 0.999)
  3. 得到可用分钟数计算得出约 43.2 分钟,这就是一个月能“浪费”的时间上限。
    43200×0.001=43.2\displaystyle 43200 \times 0.001 = 43.2

燃烧率监控:给花钱速度装仪表盘

有了预算和消耗记录,家庭财务里下一个刚需就是:花钱速度监控。你不能等到月底才发现钱花光了,而是要在月中看到“按这个速度花下去,月底前就会破产”。这个“花钱速度”,在 SRE 里叫燃烧率(Burn Rate)。

燃烧率衡量的是:当前错误率相当于预算额度被烧掉的速度有多快。如果错误率刚好等于错误预算的比例,燃烧率就是 1——意味着每个月的最后一天,预算恰好烧完。如果错误率是预算的两倍,燃烧率就是 2——预算会在半个月内耗尽。

实际工程中,我们不只监控一个燃烧率,而是多窗口多阈值同时观察。就像开车既看瞬时速度仪表盘,也看平均速度记录仪:1 小时窗口的燃烧率高,可能只是瞬时抖动;14 天窗口的燃烧率稳定在高位,才是真正的危机。

Google SRE 手册推荐了经典策略:当 14 天窗口燃烧率达到 2(即按此速度 7 天烧完月度预算)时触发告警,提示团队排查;当 1 小时窗口燃烧率达到 14.4 时,说明情况极度紧急,需要立即响应。多窗口的好处是兼顾“灵敏度”和“准确度”——短窗口抓突发,长窗口抓趋势。

把燃烧率想象成汽车的油表警示灯:不是等油箱空了才加(预算耗尽),而是油量低于四分之一就提醒(燃烧率超标)。这样团队就能在预算烧完之前主动行动,而不是被动挨打。

燃烧率=错误率错误预算=E1−SLO\displaystyle \text{燃烧率} = \frac{\text{错误率}}{\text{错误预算}} = \frac{E}{1 - \text{SLO}}
燃烧率是错误预算体系最重要的预警指标。它把“当前有多危险”浓缩成一个数字:1 倍表示匀速消耗,2 倍表示半个月烧完,14 倍表示两天内烧完。
  1. 错误率符号E 表示当前实际错误率,即单位时间内失败请求占比,例如 0.002。
    E=0.002\displaystyle E = 0.002
  2. 分母含义1 - SLO 是允许的错误比例,即错误预算,例如 SLO=0.999 时分母为 0.001。
    1−SLO=0.001\displaystyle 1 - \text{SLO} = 0.001
  3. 整体运算实际错误率除以允许错误率,得到当前消耗速度是预算的几倍。
    0.0020.001=2\displaystyle \frac{0.002}{0.001} = 2

决策策略:超支时按下暂停键

当错误预算消耗殆尽,或燃烧率持续超标时,家庭就要开启“紧急省电模式”:取消所有非必要购物、减少外出聚餐、把每一分钱都花在刀刃上。在 SRE 世界里,这套动作就是开发冻结与发布放缓。

开发冻结听起来很严厉——“所有新功能不许上线!”——但它有非常清晰的目的:当系统可靠性已经透支时,继续叠加新功能只会让故障雪上加霜。正确的做法是暂停创新投入,把全部资源转向稳定性修复:修 Bug、优化架构、扩充容量,先把“健康”找回来。

怎么判断什么时候该冻结?不能等到预算归零(那已经出大事故了),而要结合燃烧率预测耗尽时间:

当预测耗尽天数小于某个阈值(比如 3 天),团队就应该紧急冻结;如果还剩一半预算且燃烧率平稳,则可以继续正常发布,只是降低频率。除了“冻结”这个硬措施,还有“放缓”这个软措施:把每周多次发布调整为每周一次,把全量发布改为分批灰度(先 5% 用户,再 20%,最后全量),让风险逐步释放。

当然,决策不能只靠运维单方面拍板。开发冻结是“全家的决定”——产品、研发、运维共同看着账本开会讨论:这个预算消耗速度能不能接受?要不要为下周的大促保留预算?这才是错误预算真正发挥作用的地方:它把稳定性决策从“吵架”变成“看数据”。

T耗尽=剩余预算平均每日错误率\displaystyle T_{\text{耗尽}} = \frac{\text{剩余预算}}{\text{平均每日错误率}}
这个公式像“剩余钱 ÷ 日均开销 = 还能撑几天”。它把抽象的风险转化为具体的截止日期,团队据此决定:是立刻冻结发布,还是可以再观察两天。
  1. 分子含义剩余预算指本月尚未消耗的错误额度,如还剩 0.0003。
    剩余预算=0.0003\displaystyle \text{剩余预算} = 0.0003
  2. 分母含义平均每日错误率,是近期每日失败占比的平均值,反映当前消耗速度。
    平均每日错误率=0.00002\displaystyle \text{平均每日错误率} = 0.00002
  3. 整体运算剩余额度除以每日消耗,得到在现有速度下还能维持的天数。
    0.00030.00002=15 天\displaystyle \frac{0.0003}{0.00002} = 15\ \text{天}

团队协作:全家人一起管理账本

错误预算能运转的前提是:全家人都认可同一本账。如果运维团队自己记账,研发团队不认账,产品经理继续催需求,那这套机制就形同虚设。所以 Google 强调,SLO 和错误预算必须是业务、研发、运维三方共同商定、共同遵守的契约。

这个契约建立的过程,通常由定期的“预算对账会”来维护:每周或每两周,团队坐下来看一次错误预算消耗率、燃烧率趋势、近期发布计划。产品的角色是解释“下周要上线什么功能、预期风险多大”;研发的角色是汇报“已知故障修复进展”;运维的角色是提供数据、给出建议。

为了让不同角色都能看懂预算状态,团队需要一个简单的可视化口径。最常用的就是剩余预算百分比——一眼就能看出“本月还剩多少犯错空间”:

有了这个进度条,团队协作就从“你说我不稳,我说你太慢”变成“账本显示还剩 30%,咱们一起决定怎么花”。当预算还充裕时,研发可以放心大胆地推进创新;当预算吃紧时,产品会主动点头同意冻结发布——因为所有人都知道,再烧下去受影响的是最终用户,而用户是大家的共同底线。

这种“共担预算”的文化,本质上是一种问责机制:每个团队都对自己的改动负责。如果你的功能发布导致错误预算烧掉一半,你要站出来说明并承担修复责任。这种文化比任何制度都更有约束力,因为它让“稳定性”从运维的责任变成了每个人的责任。

剩余预算比例=剩余预算总预算×100%\displaystyle \text{剩余预算比例} = \frac{\text{剩余预算}}{\text{总预算}} \times 100\%
这个比例把复杂的指标变成“账本进度条”:100% 表示刚刚开始,0% 表示预算耗尽。团队会议第一件事就是看这个数字,就像看股票行情一样直观。
  1. 分子含义剩余预算 = 总预算 - 已消耗预算,是账本上还没花掉的额度。
    剩余预算=总预算−已消耗预算\displaystyle \text{剩余预算} = \text{总预算} - \text{已消耗预算}
  2. 分母含义总预算即月度错误预算(1 - SLO),是本月可用的完整额度。
    总预算=1−SLO\displaystyle \text{总预算} = 1 - \text{SLO}
  3. 整体运算两者相除再乘以 100%,得到剩余比例。
    剩余预算1−SLO×100%\displaystyle \frac{\text{剩余预算}}{1 - \text{SLO}} \times 100\%

实践落地:从理论到工程落地

理论讲得再好,最终还得落到工具和流程上。把错误预算体系落地到团队,通常分三步:定指标、接监控、跑闭环。

定指标是第一步。先想清楚“系统的成功到底怎么定义”——是请求成功率?还是视频播放无卡顿率?还是订单支付成功率?这一步最考验业务理解能力。以 AI 平台为例,如果你服务的是一个模型推理接口,SLO 可能定义为“90% 的请求在 500ms 内返回”或“服务可用性 99.5%”;但如果你服务的是离线训练任务,SLO 可能就变成“每周任务调度成功率 ≥ 99%”。选错指标,整个错误预算体系就建在沙地上。

接监控是让数字自动流动起来。用 Prometheus 采集错误数据,用 Grafana 画出月度错误预算消耗曲线,用 Alertmanager 在燃烧率超过阈值时自动告警。现代监控平台(如 Google Cloud Monitoring、Datadog)甚至内置了 SLO/错误预算面板:

跑闭环是让体系持续运转。每月初复盘上月预算消耗情况:哪次发布消耗最多?哪个故障贡献最大?这些数据沉淀下来,反过来优化下个月的 SLO 设定和发布策略。比如发现“每月大促期间预算必然消耗超 50%”,就可以提前在促销前冻结其他发布,把预算专门留给大促。

最后,随着业务演进,SLO 和错误预算也要持续迭代。一个成熟团队不会让 SLO 一年不变,而是每季度审视一次:用户对延迟的容忍度变了吗?竞品做到了什么水平?我们是否应该收紧 SLO 以提升用户满意度?让错误预算体系像家庭的年度财务规划一样,跟着生活状况不断调整。

告警窗口=目标窗口燃烧率阈值\displaystyle \text{告警窗口} = \frac{\text{目标窗口}}{\text{燃烧率阈值}}
这个公式用于反向设计告警策略:如果你想在“2 天烧完预算”时就收到告警,而目标窗口是 30 天,那么告警燃烧率阈值应设为 30 / 2 = 15 倍。它把“多快触发告警”和“燃烧率阈值”直接对应起来。
  1. 目标窗口指一个完整预算周期的天数,通常为 30 天(月度预算)。
    目标窗口=30 天\displaystyle \text{目标窗口} = 30\ \text{天}
  2. 燃烧率阈值希望触发告警的消耗速度倍数,比如 15 倍意味着 2 天烧完月度预算。
    燃烧率阈值=302=15\displaystyle \text{燃烧率阈值} = \frac{30}{2} = 15
  3. 告警窗口当瞬时窗口短于此告警窗口时触发提醒,例如 1 小时窗口。
    告警窗口=3015=2 天\displaystyle \text{告警窗口} = \frac{30}{15} = 2\ \text{天}

AI 应用场景

场景 1:AI 推理服务发布决策

阶段:模型部署与上线运维阶段

解决的问题:传统模式下,模型推理服务(如大语言模型 API)上新版本时,运维团队只能在“上线新模型快速迭代”和“保持服务稳定”之间来回拉扯。没有统一标准时,每次发布都靠人工评估风险,发布后出了问题才后悔莫及。引入错误预算后,团队预先设定 SLO(如“推理服务月可用性 ≥ 99.5%”),本月错误预算消耗未超 50% 时,模型新版本可以按正常节奏灰度发布;预算消耗超 80% 时自动触发发布冻结,保证剩余预算用于修复已知问题。

具体案例:某 LLM 推理平台在 3 月中旬连续遭遇两次上游故障,错误预算从月初的 100% 骤降至 35%。原定周五发布的推理优化新版本被自动延期至下月初,团队将精力集中到接入备用上游通道,系统稳定后预算回升,新模型才重新进入灰度流程。

场景 2:AI 训练平台容量规划

阶段:资源调度与容量管理阶段

解决的问题:AI 训练平台常有“任务调度失败率”这一 SLO。团队用错误预算机制管理 GPU 集群的稳定性:如果某个新的调度策略频繁导致任务失败、快速烧掉预算,就回滚策略;如果预算剩余充足,则允许调度器激进地做资源超卖以提高 GPU 利用率。这套机制让“提高资源效率”和“保证任务成功率”不再互相矛盾。

具体案例:某公司 AI 平台将“SLO = 训练任务调度成功率 99%”,错误预算为每月 1%(约 7.2 小时失败时间)。一次大规模 checkpointer 升级引发调度失败潮,2 小时内耗尽预算并触发燃烧率告警,平台自动关闭了新调度实验开关,任务成功率恢复后,团队才重新小范围验证升级方案。

Python 演示

python56 行
class ErrorBudgetTracker:    def __init__(self, slo=0.999, month_days=30):        self.slo = slo        self.month_days = month_days        self.total_budget = 1.0 - slo        self.daily_errors = []        self._window_span = 7     def record_daily_error(self, error_rate):        self.daily_errors.append(error_rate)     def spent_budget(self, latest_index=None):        end = latest_index if latest_index is not None else len(self.daily_errors)        return sum(self.daily_errors[:end])     def remaining_budget(self):        return max(0.0, self.total_budget - self.spent_budget())     def current_burn_rate(self, window=None):        size = window or len(self.daily_errors)        if size == 0:            return 0.0        recent = self.daily_errors[-size:]        daily_budget = self.total_budget / self.month_days        avg_error = sum(recent) / len(recent)        if daily_budget == 0:            return 0.0        return avg_error / daily_budget     def forecast_exhaustion_day(self):        if not self.daily_errors:            return None        avg = sum(self.daily_errors) / len(self.daily_errors)        if avg <= 0:            return None        return len(self.daily_errors) + self.remaining_budget() / avg     def freeze_required(self, burn_threshold=2.0):        burn = self.current_burn_rate(self._window_span)        return burn >= burn_threshold or self.remaining_budget() <= 0  if __name__ == "__main__":    tracker = ErrorBudgetTracker(slo=0.999, month_days=30)    daily_rates = [0.0005, 0.0006, 0.0004, 0.0020, 0.0030,                   0.0010, 0.0015, 0.0008, 0.0009, 0.0012]    for rate in daily_rates:        tracker.record_daily_error(rate)        print("Day %2d | spent=%.5f | remaining=%.5f | burn(7d)=%.2f"              % (len(tracker.daily_errors),                 tracker.spent_budget(),                 tracker.remaining_budget(),                 tracker.current_burn_rate(tracker._window_span)))    exhaustion = tracker.forecast_exhaustion_day()    print("Forecast exhaustion day: %s" % ("%.1f" % exhaustion if exhaustion else "never"))    print("Freeze required: %s" % tracker.freeze_required())
目的:这是一个极简错误预算跟踪器,用 Python 模拟了 SLO=99.9% 的服务在 10 天内的预算消耗、燃烧率计算、耗尽预测与冻结决策。
  1. self.total_budget = 1.0 - slo根据 SLO 计算月度总错误预算(0.1% 即 0.001),这是账本的“总收入”。
  2. self.daily_errors = []用列表记录每天的实测错误率,相当于每日记账流水。
  3. def spent_budget累计所有已记录的错误率,算出本月已消耗的预算比例。
  4. def remaining_budget总预算减去已消耗,得到剩余额度(最低为 0,不出现负值)。
  5. daily_budget = self.total_budget / self.month_days把月度预算摊到每天,得到每日允许错误率,这是燃烧率的分母。
  6. return avg_error / daily_budget实际日均错误率除以允许日均错误率,得到燃烧率:大于 1 就在加速烧钱。
  7. def forecast_exhaustion_day用剩余预算除以日均消耗,预测第几天会破产。
  8. def freeze_required判断是否触发冻结:近 7 天燃烧率 ≥ 2,或剩余预算已归零。

常见误区

误区“我们的服务很重要,SLO 必须设成 100%,不允许任何错误!这样用户满意度最高。” 许多人认为把目标定到完美,系统就一定更可靠。

正解SLO=100% 意味着错误预算为 0,团队没有任何犯错空间。现实中任何分布式系统都会因网络抖动、机器故障、代码 Bug 产生错误,100% 的目标只会让团队永远处于“预算已耗尽”的冻结状态,新功能寸步难行。SRE 的智慧恰恰是主动承认不完美,留出预算给创新。这就像要求孩子次次考满分,结果孩子只能天天刷题,再也没有时间发展其他兴趣。

为何常见:人们习惯性把“高目标”等同于“高执行力”,却忽略了一个可量化的容错空间才是持续改进的前提。

误区“总预算 43 分钟,现在才花了 10 分钟,还剩好多,不用着急吧?” 团队只盯着剩余预算的绝对值,忽略了消耗的速度。

正解剩余预算只是“存量”,燃烧率才是“流速”。如果当前燃烧率是 5 倍,意味着 6 天内就会烧完剩下的 33 分钟。错误预算的真正价值在于提前预警——就像油箱还有半箱油,但按当前油耗只能再开 100 公里,就该找加油站了。SRE 依赖多窗口燃烧率告警,正是为了在预算耗尽前捕获风险。

为何常见:人脑天然对“绝对剩余量”敏感,而对“速率”这种需要换算的指标不够直观,导致忽视趋势性风险。

误区“SLO 是运维定的、告警是运维看的、冻结是运维宣布的,和研发、产品没关系。” 这种观点把稳定性工作完全甩给运维。

正解错误预算的灵魂在于共同契约。SLO 需要研发(评估发布风险)、产品(决定功能优先级)、运维(提供数据)共同制定。预算被研发的新功能烧掉,研发就要出来解释;冻结发布时产品要说“哪些功能可以延后”。只有所有人都认这本账,错误预算才能真正指导决策,否则只是运维单方面的“自我感动”。

为何常见:传统组织架构中稳定性天然被归为运维职责,而错误预算恰好是要打破这种边界,让所有人对用户可用性共同负责。

误区“反正下个月 1 号预算就恢复了,这个月超了也没事,熬到月底就行。” 认为月度重置机制可以掩盖当月的问题。

正解月度重置只是“账本清零”,不代表问题消失。如果当月预算因严重事故耗尽,说明系统存在需要修复的架构缺陷。SRE 团队的规范做法是预算耗尽后必须进行事故复盘(Postmortem),找到根因并推进修复,而不是干等月底翻篇。否则下个月同样的事故会再次把预算瞬间烧光。

为何常见:月度结算的财务思维让人们习惯了“本月亏损下月重来”,但稳定性问题不会因为日历翻页而自动消失。

误区“燃烧率超过 1 就告警,超过 2 就紧急响应,一个阈值搞定所有场景。” 有人试图用单一燃烧率阈值覆盖所有风险。

正解单一阈值要么太灵敏(频繁误报导致告警疲劳),要么太迟钝(严重故障未被及时发现)。SRE 采用多窗口多阈值策略:1 小时窗口 14.4 倍燃烧率抓突发严重故障(如大面积宕机),6 小时窗口 6 倍抓快速蔓延问题,14 天窗口 2 倍抓慢性恶化趋势。不同窗口组合才能兼顾灵敏度与准确度,就像医生既量心率又测血压,多项指标联合判断病情。

为何常见:简单化思维倾向于找一个万能阈值,但真实系统的风险形态多样,需要组合信号才能全面覆盖。

面试题

Q1. 当服务 SLO 设为 99.9% 时,错误预算是多少?

单选题 · easy

  • A.0.1%← 正确答案
  • B.1%
  • C.0.01%
  • D.10%

答案:A。错误预算 = 1 - SLO。当 SLO = 0.999 时,预算 = 1 - 0.999 = 0.001,即 0.1%。它就像家庭每月留出的“娱乐额度”——不是收入的全部,而是允许灵活支配的固定比例。

Q2. 某服务 SLO 为 99.9%,按 30 天月计算,每月错误预算大约是多少分钟?

单选题 · mid

  • A.4.3 分钟
  • B.43.2 分钟← 正确答案
  • C.432 分钟
  • D.7.2 分钟

答案:B。30 × 24 × 60 × (1 - 0.999) = 43200 × 0.001 = 43.2 分钟。这 43.2 分钟是整个月累计允许的系统不可用时间,相当于一个月的“容错额度”,用完即触发冻结决策。

Q3. 燃烧率为 1 倍的含义是什么?

单选题 · easy

  • A.预算在月底恰好耗尽← 正确答案
  • B.预算立刻耗尽
  • C.预算永远用不完
  • D.系统已经宕机

答案:A。燃烧率 = 错误率 ÷ 错误预算。1 倍表示当前错误消耗速度刚好等于预算允许的速度,按此速度持续,月底预算恰好用完。就好比每天按计划花零花钱,月末正好清零。

Q4. 当 SLO 从 99.9% 放宽到 99%,错误预算变化多少倍?

单选题 · mid

  • A.10 倍← 正确答案
  • B.100 倍
  • C.2 倍
  • D.0.1 倍

答案:A。99.9% 的预算为 0.1%,99% 的预算为 1%,1% ÷ 0.1% = 10 倍。SLO 微小的放宽会带来错误预算量级的提升,就像购物预算从“每天 1 元”变成“每天 10 元”,消费自由度完全不同。

Q5. 错误预算消耗殆尽后,正确的首要动作是什么?

单选题 · mid

  • A.立即发布已开发的新功能
  • B.冻结发布并集中修复稳定性← 正确答案
  • C.扩大集群容量
  • D.等待下月预算自动恢复

答案:B。预算耗尽说明系统可靠性已透支,此时继续发布新功能只会增加风险。正确做法是冻结高风险发布、把研发资源转向修复和加固。扩容可能是修复措施之一,但不是首要策略;干等预算重置则是不负责任的做法。

Q6. 多窗口燃烧率告警策略解决了哪些问题?

多选题 · mid

  • A.能同时捕捉突发故障和慢性恶化← 正确答案
  • B.避免单一阈值频繁误报← 正确答案
  • C.完全替代人工故障排查
  • D.兼顾告警灵敏度与准确度← 正确答案

答案:ABD。短窗口(如 1 小时)捕获突发严重故障,长窗口(如 14 天)追踪慢性趋势,组合使用既灵敏又准确,同时减少误报。但告警只是发现问题的手段,不能替代人工排查演练(选项 C 错误)。

Q7. 某服务月度错误预算为 0.1%,当前平均每日错误率为 0.00002,预测预算还能支撑几天?

单选题 · hard

  • A.5 天
  • B.15 天← 正确答案
  • C.50 天
  • D.150 天

答案:B。剩余预算除以日均消耗:0.001 ÷ 0.00002 = 50 天。但月度窗口只有 30 天,50 天意味着按当前速度本月预算足够,属于安全状态。注意 A、C、D 都是干扰计算错误,本质是“剩余额度 ÷ 每日开销”的除法运算。

Q8. 下列哪项最能描述错误预算的用途?

单选题 · easy

  • A.衡量团队代码质量
  • B.量化允许出错的空间并指导发布决策← 正确答案
  • C.计算服务器硬件成本
  • D.预测用户增长趋势

答案:B。错误预算 = 1 - SLO,它把“可用性目标”转化为“可犯错空间”,作为发布与否、冻结与否的客观依据。它与代码质量、成本、增长无关,所以其余选项都是混淆项。

Q9. 下列哪些做法符合错误预算的最佳实践?

多选题 · hard

  • A.预算耗尽后开展事故复盘并推进修复← 正确答案
  • B.预算充足时允许新功能灰度发布← 正确答案
  • C.燃烧率超标时立即全量回滚所有服务
  • D.业务、研发、运维共同商定 SLO← 正确答案

答案:ABD。预算管理强调“共同契约”(D)、“存量看剩余、流速看燃烧率”(B)、“事后复盘”(A)。而 C 全量回滚所有服务过于激进,正确做法是评估燃烧率窗口后分级响应,而非一刀切回滚。

Q10. 为什么 SLO 不应设为 100%?

单选题 · mid

  • A.100% 会导致错误预算为零,团队不敢创新← 正确答案
  • B.100% 会让监控成本无限增大
  • C.100% 无法被数学公式表达
  • D.100% 会导致用户期望过高

答案:A。SLO=100% 时错误预算 = 0,任何一次小故障都算“透支”,团队只能永远冻结发布以维持不可能的目标。SRE 承认系统必然出错,用预算留出创新空间。监控成本和用户期望是次要的,核心是错误预算机制会完全失效。