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