SLO/SLI 全流程管理实战指南:从指标定义、错误预算到多窗口燃烧率监控
【免费下载链接】claude-skills67 Specialized Skills for Full-Stack Developers. Transform Claude Code into your expert pair programmer.项目地址: https://gitcode.com/GitHub_Trending/claud/claude-skills
本指南以 claude-skills 仓库中 sre-engineer 技能 的 SLO/SLI 管理知识体系为核心,系统讲解服务级别指标(SLI)的定义模式、服务级别目标(SLO)的 YAML 配置、四大黄金信号、错误预算计算、多窗口合规追踪与燃烧率告警的完整闭环。读完本文,你将能够在生产服务中从零落地一套可度量、可告警、可持续优化的 SLO 体系,并理解其底层计算原理。
背景:这份指南在 claude-skills 仓库中的位置
claude-skills 是一个面向全栈开发者的技能库(67 个专业技能),其中sre-engineer技能专注于站点可靠性工程,其描述明确覆盖"defining SLIs/SLOs、managing error budgets、building reliable systems at scale"。该技能的核心工作流(见 SKILL.md)是:
- Assess reliability- 审查架构、SLO、事故与运维损耗水平
- Define SLOs- 识别有意义的 SLI 并设置合理目标
- Verify alignment- 在推进前确认 SLO 目标反映用户预期
- Implement monitoring- 构建黄金信号看板与告警
- Automate toil- 识别重复性任务并构建自动化
- Test resilience- 设计并执行混沌实验,验证恢复满足 RTO/RPO
本指南对应的 slo-sli-management.md 正是其中第 2、3、4 步的深度参考文档,由 SKILL.md 的 Reference Guide 表格在"Defining SLOs, calculating error budgets"场景下自动加载。它与其他三份参考文档——error-budget-policy.md、monitoring-alerting.md、automation-toil.md——共同构成了 SLO 从定义、追踪到告警、治理的完整链路。
SLI 定义模式:把"服务好坏"变成可量化的数字
服务级别指标(Service Level Indicator, SLI)是服务行为的定量测量结果。它是整个 SLO 体系的基石——先有可靠的 SLI 测量,才有可信的 SLO 目标。文档给出了两类最常用的 SLI 模式。
请求型 SLI(Request-Based):可用性指标
可用性 SLI 的本质是"成功请求的比例",其关键设计决策在于:哪些事件算"好事件",哪些算"总事件"。
# Availability SLI: Proportion of successful requests # Good events: HTTP 200-299, 4XX (client errors don't count against SLI) # Total events: All requests def calculate_availability_sli(metrics): """Calculate availability SLI from request metrics.""" successful_requests = metrics['http_2xx'] + metrics['http_4xx'] total_requests = metrics['total_requests'] if total_requests == 0: return 1.0 # No traffic = 100% available return successful_requests / total_requests这段代码包含两个重要的工程决策点,值得展开说明:
- 4XX 不计入失败:客户端错误(如 404、400)说明是调用方的问题,而不是服务不可用。把它们从"好事件"中剔除会扭曲可用性指标,把它们算作"失败事件"又会对服务进行错误惩罚。因此这里的"好事件"由 2xx 与 4xx 共同构成。若要严格统计,更精确的做法是只用
status=~"2.."(见下文 PromQL 查询),两种口径在实践中的差异正是 SLI 需要团队达成一致的地方。 - 零流量边界:当
total_requests == 0时返回1.0(视为 100% 可用),避免了除零错误,同时符合"无流量即无失败"的直觉。这也是所有 SLI 计算函数必须处理的边界条件,后续的延迟 SLI 函数中同样可见这一模式。
延迟型 SLI(Latency-Based):性能指标
延迟 SLI 从直方图(histogram)数据中计算"快于阈值的请求比例"。这与 Prometheus 的http_request_duration_seconds_bucket直方图数据结构完全对应——按le(less than or equal)分桶的累计计数器。
def calculate_latency_sli(latency_histogram, threshold_ms=500): """Calculate latency SLI from histogram. Args: latency_histogram: dict mapping latency buckets to request counts threshold_ms: latency threshold in milliseconds Returns: float: Proportion of requests faster than threshold """ fast_requests = sum( count for bucket, count in latency_histogram.items() if bucket <= threshold_ms ) total_requests = sum(latency_histogram.values()) return fast_requests / total_requests if total_requests > 0 else 1.0threshold_ms(默认为 500ms)是该函数的唯一调优点:它应当取自 SLO 目标(例如"99% 的请求在 500ms 内完成"),而非随意设置。在 claude-skills 的 monitoring-alerting.md 中,延迟 SLI 在 Prometheus 侧的等价实现是:
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service))两种表示法互为印证:Python 版本适合在离线计算、回归测试或非 Prometheus 系统中实现 SLI;PromQL 版本则适合在监控系统内实时计算 P99 分位数。
SLO 配置:一份可提交到仓库的 YAML 定义
文档给出了生产 API 的 SLO 定义示例。这份 YAML 是可版本化、可评审的 SLO 清单,同时覆盖了可用性与延迟两类 SLO:
# slo_config.yaml - Production API SLO definitions apiVersion: sre/v1 kind: ServiceLevelObjective metadata: service: payment-api environment: production spec: slos: - name: availability description: "Users can successfully complete payment requests" sli: metric: http_requests_total query: | sum(rate(http_requests_total{status=~"2..|4..", service="payment-api"}[30d])) / sum(rate(http_requests_total{service="payment-api"}[30d])) target: 0.999 # 99.9% window: 30d - name: latency description: "Payment requests complete quickly" sli: metric: http_request_duration_seconds query: | histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket{service="payment-api"}[30d])) by (le) ) < 0.5 target: 0.99 # 99% of requests under 500ms window: 30d对该配置逐字段解析如下:
| 字段 | 取值 | 含义 |
|---|---|---|
apiVersion/kind | sre/v1/ServiceLevelObjective | 定义 SLO 对象类型,便于与 GitOps 工具链集成 |
metadata.service | payment-api | 目标服务名,必须与指标中的service标签一致 |
metadata.environment | production | 环境隔离,同一服务在生产与预发可以有不同 SLO |
spec.slos[].name | availability/latency | SLO 名称,用于告警标签与看板分组 |
spec.slos[].sli.query | PromQL | 完整定义 SLI 的度量方式,保证"计算方式透明" |
spec.slos[].target | 0.999/0.99 | 目标值,直接决定错误预算的大小 |
spec.slos[].window | 30d | 合规评估的时间窗口,错误预算即按此窗口计算 |
注意两个 SLO 的查询都使用[30d]时间范围,与window: 30d保持一致——如果查询窗口与 SLO 窗口不一致,错误预算计算将失真。延迟 SLO 的查询用histogram_quantile(0.95, ...) < 0.5表达"P95 延迟小于 0.5 秒",而target: 0.99表示目标要求 99% 的时间满足该条件,即一个"目标中的目标"(quantile 目标嵌套在 SLO 目标内)。
四大黄金信号:每个服务都应该测量的指标
Google SRE 提出的四大黄金信号是 SLI 设计的起点。文档用 Pythondataclass形式给出了完整的信号建模,将"监控什么"固化为可校验的数据结构:
from dataclasses import dataclass from typing import Dict @dataclass class GoldenSignals: """Four golden signals of monitoring.""" # Latency: Time to service requests (success vs failure) latency_p50_ms: float latency_p95_ms: float latency_p99_ms: float # Traffic: Demand on your system (requests/sec) requests_per_second: float # Errors: Rate of failed requests error_rate: float # 0.0 to 1.0 # Saturation: How "full" is your service (CPU, memory, disk) cpu_utilization: float # 0.0 to 1.0 memory_utilization: float # 0.0 to 1.0 def is_healthy(self, slo_targets: Dict[str, float]) -> bool: """Check if all signals are within SLO targets.""" return ( self.latency_p99_ms <= slo_targets['latency_p99_ms'] and self.error_rate <= (1 - slo_targets['availability']) and self.cpu_utilization <= slo_targets['max_cpu'] and self.memory_utilization <= slo_targets['max_memory'] )四大信号的定义与解读:
- Latency(延迟):服务请求的处理时间,且需区分成功与失败请求的延迟。文档取 P50/P95/P99 三个分位点,因为"平均延迟"无法反映尾部请求的糟糕体验——P99 才是用户体验的下限。
- Traffic(流量):系统承受的需求,通常以 QPS/RPS 衡量,用于识别流量异常与容量规划。
- Errors(错误率):失败请求的比例,取值 0.0~1.0。可用性 SLO 与错误率的关系是
error_rate <= 1 - availability,这是is_healthy()中self.error_rate <= (1 - slo_targets['availability'])的直接来源。 - Saturation(饱和度):服务的"满载程度",典型指标为 CPU、内存、磁盘利用率。
is_healthy()方法将四大信号与 SLO 目标做一次综合判定,可作为看板健康状态的程序化依据。在仓库的 monitoring-alerting.md 中,这四大信号有对应的 Prometheus recording rules(service:http_request_duration_seconds:p99、service:http_requests:error_rate5m、service:cpu_utilization等),即"代码中的黄金信号"与"监控中的黄金信号"一一映射。
SLO 计算示例:错误预算与允许停机时间
SLO 目标一旦设定,就可以推导出两个运营关键数字:错误预算(error budget)和允许停机时间。
from datetime import timedelta from typing import NamedTuple class SLOTarget(NamedTuple): """SLO target configuration.""" target: float # 0.999 for 99.9% window: timedelta # 30 days @property def error_budget(self) -> float: """Calculate error budget (1 - target).""" return 1 - self.target @property def allowed_downtime(self) -> timedelta: """Calculate allowed downtime in window.""" total_seconds = self.window.total_seconds() allowed_seconds = total_seconds * self.error_budget return timedelta(seconds=allowed_seconds) # Example SLOs availability_slo = SLOTarget(target=0.999, window=timedelta(days=30)) print(f"Error budget: {availability_slo.error_budget * 100}%") print(f"Allowed downtime: {availability_slo.allowed_downtime}") # Output: # Error budget: 0.1% # Allowed downtime: 43.2 minutes per 30 days latency_slo = SLOTarget(target=0.99, window=timedelta(days=30)) print(f"99% of requests must be fast") print(f"1% can be slow: {latency_slo.error_budget * 100}%")核心公式:
error_budget = 1 - target:99.9% 目标的错误预算为 0.1%,即"允许的不可靠性"。allowed_downtime = window * error_budget:30 天窗口下 0.1% 允许停机30 × 24 × 60 × 0.001 = 43.2分钟。
需要强调的是,错误预算既可以用"时间"表达(停机分钟数),也可以用"请求数"表达。SKILL.md 的 Concrete Examples 部分给出了请求维度的换算:"10M requests/month → 10,000 error budget requests;如果第 1 周就消耗了 5,000 个,则预算烧掉了 50% 而时间只过了 25%"——这就是触发错误预算策略(如冻结非关键发布)的依据。时间与请求两种口径的换算关系是:error_budget_requests = total_requests × (1 - target)。
多窗口 SLO 追踪与错误预算燃烧率
单个 30 天窗口的合规判断过于粗粒度——它无法回答"这个小时我们是不是在加速变坏"。文档给出的MultiWindowSLO类解决了这个问题:
class MultiWindowSLO: """Track SLO compliance across multiple time windows.""" def __init__(self, target: float): self.target = target self.windows = { '1h': timedelta(hours=1), '24h': timedelta(hours=24), '7d': timedelta(days=7), '30d': timedelta(days=30), } def check_compliance(self, sli_values: Dict[str, float]) -> Dict[str, bool]: """Check if SLI meets target in each window. Args: sli_values: Dict mapping window name to measured SLI Returns: Dict mapping window name to compliance boolean """ return { window: sli >= self.target for window, sli in sli_values.items() } def get_burn_rate(self, current_sli: float) -> float: """Calculate error budget burn rate. Burn rate > 1.0 means burning budget faster than sustainable. """ error_budget = 1 - self.target current_error_rate = 1 - current_sli if error_budget == 0: return float('inf') return current_error_rate / error_budget燃烧率(burn rate)是本节的精髓,计算公式为:
burn_rate = current_error_rate / error_budget = (1 - SLI) / (1 - SLO target)burn_rate = 1.0:按可持续速度消耗预算(这是"正常"状态)。burn_rate = 3.0:以 3 倍于可持续的速度烧预算,30 天预算将在约 10 天耗尽。- 从 30 天窗口推导的具体告警阈值,文档注释给出的是经典多窗口策略(源自 Google SRE Workbook):1 小时内消耗 2% 预算对应燃烧率 14.4x(2% × 30 天 ÷ 1 小时),6 小时内消耗 5% 预算对应 6x,3 天消耗 10% 对应 1x。
这套阈值在仓库中并非孤例——error-budget-policy.md 中用BurnRateAlertNamedTuple 完整建模了这三种告警档位:
BURN_RATE_ALERTS = [ # Fast burn: 2% budget in 1 hour = exhausted in 2 days BurnRateAlert( window=timedelta(hours=1), burn_rate_threshold=14.4, # 2% of 30d budget in 1h budget_consumed_threshold=0.02 ), # Medium burn: 5% budget in 6 hours BurnRateAlert( window=timedelta(hours=6), burn_rate_threshold=6.0, budget_consumed_threshold=0.05 ), # Slow burn: 10% budget in 3 days BurnRateAlert( window=timedelta(days=3), burn_rate_threshold=1.0, budget_consumed_threshold=0.10 ), ]在真实监控系统中,多窗口燃烧率通过 PromQL 实现,SKILL.md 给出了完整的告警规则(HighErrorBudgetBurn快烧告警与SlowErrorBudgetBurn慢烧告警):
groups: - name: slo_availability rules: # Fast burn: 2% budget in 1h (14.4x burn rate) - alert: HighErrorBudgetBurn expr: | ( sum(rate(http_requests_total{status=~"5.."}[1h])) / sum(rate(http_requests_total[1h])) ) > 0.014400 and ( sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) ) > 0.014400 for: 2m labels: severity: critical该规则的精妙之处在于and组合两个时间窗口:只有短窗口(5m)和长窗口(1h)同时超阈值才触发,从而避免瞬时毛刺造成的告警风暴;for: 2m进一步要求条件持续 2 分钟才告警。0.0144 的来源是 99.9% 目标的错误预算 0.1% × 14.4x。
从 SLO 到错误预算策略:超出预算后怎么办
多窗口追踪的价值在于触发治理动作。文档的 SLO Review Checklist 第 6 条要求"是否有错误预算策略",error-budget-policy.md 提供了完整的策略模板,按剩余预算划分四个运营状态:
| 剩余预算 | 状态 | 典型动作 |
|---|---|---|
| 100% | normal_operations | 正常开发、业务时间部署、标准变更评审 |
| 50% | careful_operations | 加强代码评审、部署需高级工程师批准、预部署风险评估 |
| 25% | restricted_operations | 暂停非关键功能开发、只部署关键修复、每日预算评审 |
| 0% | feature_freeze | 立即冻结功能、只允许紧急修复、全员可靠性评审 |
该文档还给出了部署决策框架(should_deploy函数):预算耗尽时只有critical业务优先级才允许部署;预算紧张(<25%)时高风险变更一律拒绝。这为"用错误预算驱动发布节奏"提供了可执行的程序化判断。
在监控侧,monitoring-alerting.md 提供了配套的 Grafana 看板生成代码与告警设计原则(好的告警必须可行动而非仅提供信息),以及可用性 SLI、剩余预算百分比、1h 燃烧率的 PromQL 看板面板,正好覆盖本文第三节配置的两个 SLO 的日常观测。
SLO 评审清单:发布前逐条自查
文档在收尾处给出了定稿 SLO 前的六条检查项。这是将"拍脑袋定目标"转化为"可信承诺"的质量关卡:
- User-centric(以用户为中心):是否度量用户可感知的影响?SLO 应反映用户体感,而非内部运维指标。
- Achievable(可实现):以当前架构能否达成?不可达的目标会导致告警疲劳和信任崩塌。
- Measurable(可度量):能否准确追踪对应的 SLI?没有可靠埋点就没有 SLO。
- Meaningful(有意义):违反它是否需要采取行动?若违反也不影响任何决策,这个 SLO 就是噪音。
- Documented(有文档):计算方式是否清晰且被团队认可?SLI 定义、查询语句必须在文档中公开留痕。
- Budgeted(有预算):是否有错误预算策略?SLO 必须与发布治理机制联动才完整。
这与 SKILL.md 中 MUST DO 的"Set SLOs without user impact justification"禁令形成呼应——SLO 的合法性来自用户影响,而非工程团队的主观偏好。
常见 SLO 目标:按服务等级分层设置
不同重要性的服务应当采用不同的 SLO 目标。文档给出了三级服务的分层建议:
# Typical SLO targets by service tier tier_1_critical: availability: 99.99% # 4m 23s downtime/month latency_p99: 100ms tier_2_important: availability: 99.9% # 43m 28s downtime/month latency_p99: 500ms tier_3_standard: availability: 99.5% # 3h 37m downtime/month latency_p99: 1000ms解读要点:
- 每升一个数量级的可用性目标(99.9% → 99.99%),允许停机时间会缩小约 10 倍,这意味着对架构冗余、故障转移和监控精度的要求呈指数上升。不要对所有服务一刀切地追求 99.99%——达到它需要成本,而成本应该只花在真正关键的服务上。
- 延迟目标与可用性目标通常是"正交"的:支付 API 可能同时要求 99.9% 可用且 P99 < 500ms,二者分别由不同 SLI 支撑。
- 月度允许停机时间换算公式:
30 × 24 × 60 × (1 - availability)。99.99% 约为 4.32 分钟,99.9% 约为 43.2 分钟,99.5% 约为 216 分钟(约 3.6 小时),与 YAML 注释中的数值一致。
落地路径:把本文内容接入你的监控体系
结合 claude-skills 仓库中 sre-engineer 技能的完整资料链,一套可落地的 SLO 实践路径可以概括为五步:
- 选 SLI:用本文第二、四节的模式定义请求型/延迟型 SLI,并确保覆盖四大黄金信号。
- 定 SLO 与错误预算:按本文第六节公式与第九节分层目标确定 target、window,计算错误预算与允许停机时间。
- 配置 Prometheus recording rules:参考 monitoring-alerting.md 中的
prometheus_rules.yaml,将 P50/P95/P99、错误率、饱和度预计算为service:*系列指标。 - 部署多窗口燃烧率告警:采用本文第七节的 14.4x/6x/1x 三档告警,规则模板见 SKILL.md 的 Concrete Examples 部分。
- 绑定错误预算策略:将 error-budget-policy.md 中的四状态策略与发布流程集成,让错误预算真正成为发布闸门。
这套方法论在 claude-skills 仓库中均有源码级示例可直接复用:SLO 定义与错误预算计算的 Python 实现、Prometheus 告警与 recording rule 的 YAML 模板、Grafana 看板的 Python 生成代码,以及自动化降噪脚本。对想深入掌握 SRE 实践的全栈开发者而言,这是一套从"定义"到"治理"的完整参考实现。
<输出文章>
【免费下载链接】claude-skills67 Specialized Skills for Full-Stack Developers. Transform Claude Code into your expert pair programmer.项目地址: https://gitcode.com/GitHub_Trending/claud/claude-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考