3、误差预算基础:SLO、SLI、Error Budget的定义,以及如何将超时转化为Error Budget消耗

3.1 核心概念定义

在构建基于OpenTelemetry的调用链超时监控体系之前,必须统一三个核心概念的语言。误差预算(Error Budget)是SRE实践中最具操作性的管理工具,它将不可靠性量化为可消耗的“预算”。

概念 英文全称 定义 在调用链超时场景中的含义
SLI Service Level Indicator 服务等级指标,是实际测量的服务质量数值 调用链P99延迟、P95延迟、超时率、错误率
SLO Service Level Objective 服务等级目标,是SLI的目标阈值,通常以百分比形式定义 “99.9%的调用链在500ms内完成”
Error Budget Error Budget 误差预算 = 1 - SLO,表示在SLO周期内允许的不可用或超时总量 每月允许的超时调用次数或超时总时长
关键认知:误差预算不是“错误容忍度”,而是“创新与稳定性之间的货币”。当预算充足时,团队可以大胆发布新版本;当预算耗尽时,必须冻结变更、优先恢复稳定性。

3.2 三者的层级关系

SLI是底层测量,SLO是上层承诺,Error Budget是管理杠杆。下图展示了三者在调用链超时监控中的递进关系:

SLI、SLO、Error Budget层级关系图 SLI:服务等级指标 实际测量值:P99延迟 = 480ms,超时率 = 0.05% SLO:服务等级目标 承诺阈值:99.9% 的调用链在 500ms 内完成 Error Budget:误差预算 允许消耗量 = 1 - 0.999 = 0.1% 的调用链可超时 管理杠杆 预算充足 → 允许发布;预算耗尽 → 冻结变更,优先修复

3.3 如何将超时转化为Error Budget消耗

调用链超时是Error Budget最直接的消耗来源。转化过程分为三个步骤:定义超时事件、计算单次消耗、累计周期消耗。

步骤一:定义超时事件

在OpenTelemetry中,超时事件由Span属性中的status.code和status.description标识。当调用链的端到端延迟超过SLO阈值时,该调用链被标记为“超时事件”。

// OpenTelemetry Span超时标记示例
span.setStatus(StatusCode.ERROR, "调用链超时:端到端延迟 620ms,SLO阈值 500ms");
span.recordException(new TimeoutException("Error Budget消耗事件"));

步骤二:计算单次超时的预算消耗

单次超时消耗的预算量取决于SLO周期和总请求量。消耗公式如下:

单次超时消耗(单位:预算百分比)

消耗 = 1 / (总请求量 × SLO周期天数 × 每日请求量系数)

示例:月SLO周期(30天),日均请求100万次,SLO=99.9%

总预算 = 30 × 1,000,000 × 0.001 = 30,000 次超时

单次超时消耗 = 1 / 30,000 ≈ 0.0033% 的月度预算

步骤三:累计消耗与告警阈值

通过OpenTelemetry的Metrics API,将每次超时事件累加到Error Budget消耗计数器。当消耗达到预设阈值时触发告警。

消耗阶段 累计消耗比例 建议动作
绿色区 0% – 50% 正常发布,持续监控
黄色区 50% – 80% 限制高风险变更,启动根因分析
红色区 80% – 100% 冻结发布,立即修复超时问题
耗尽 > 100% 触发SLO违约复盘,调整容量或架构

3.4 超时消耗Error Budget的完整流程

下图展示了从调用链超时发生到Error Budget消耗、再到管理决策的完整闭环:

超时消耗Error Budget闭环流程图 调用链超时 P99 > SLO阈值 OTel采集 Span + Metrics 预算计算 消耗累加器 阈值判断 绿/黄/红区 告警通知 PagerDuty/钉钉 管理决策 冻结/发布/扩容 虚线反馈环:修复措施生效后,调用链超时减少,Error Budget消耗放缓

3.5 实践要点与避坑指南

  • 预算周期选择:推荐使用30天滚动窗口,避免月初/月末的边界效应。OpenTelemetry的Exemplar可以记录每次超时事件的精确时间戳,支持滚动窗口计算。
  • 超时定义一致性:SLO中的“超时”必须与OpenTelemetry的Span超时定义一致。建议在OTel Collector中配置统一的tail_sampling策略,确保超时事件被准确捕获。
  • 预算消耗速率:不要只看值,要监控消耗速率(%/小时)。如果某小时消耗了30%的月度预算,即使总量未耗尽,也应立即介入。
  • 多维度预算:不同服务、不同调用链类型(读/写、同步/异步)应设置独立的Error Budget,避免一个服务的超时拖垮全局预算。
常见陷阱:不要将Error Budget与“错误次数”直接等同。超时事件可能由客户端重试导致,单次用户请求可能产生多次超时Span。务必在OTel中通过trace_id去重,以用户感知的端到端延迟为准计算预算消耗。