10. SRE 工程: 错误预算 / 容量 / 变更 / 事件响应 / 生产就绪
TL;DR
SRE(Site Reliability Engineering,Google 创立)是"让软件可靠性成为可度量的工程"。核心理念:可靠性不是"尽量不出事",而是用错误预算(Error Budget)来平衡可靠性与迭代速度。这一章把 SRE 的方法论落到实际工作:SLI/SLO 怎么定、错误预算怎么用、容量怎么规划、变更怎么控制风险、事件怎么响应、系统怎么"生产就绪"。
读完应能:
- 说出 SRE 与普通运维的本质区别(可度量 + 自动化 + 软件工程化)。
- 设计并落地 SLI/SLO/Error Budget,用它驱动决策。
- 做容量规划(趋势预测、扩缩容策略)。
- 设计变更流程(发布窗口、回滚、卡点)。
- 跑一次完整的事件响应(发现 → 响应 → 缓解 → 复盘)。
一、SRE 是什么
1.1 SRE vs 传统运维
| 传统运维 | SRE | |
|---|---|---|
| 目标 | 系统稳定 | 稳定 + 迭代速度平衡 |
| 度量 | 靠感觉/经验 | SLI/SLO 可度量 |
| 手段 | 人肉守护 | 自动化 / 代码化 |
| 心态 | 避免一切变更 | 用错误预算管理风险 |
| 交付物 | 稳定系统 | 稳定 + 自动化工具 |
1.2 Google 的"50% 规则"
SRE 团队最多把 50% 时间花在运维(operation)上,另外 50% 必须花在工程开发(工具/自动化/架构改进)上。
这条规则逼着 SRE 用工程解决重复劳动,而不是堆人肉。
1.3 核心心智:可靠性与速度的权衡
- 可靠性 100% = 永远不发布 = 产品死。
- 可靠性 0% = 疯狂发布 = 用户跑。
- 正确姿势:定一个目标(如 99.9%),剩下 0.1% 的"错误预算"用来"花钱"——可以拿来发布新功能、可以拿来冒险。
二、SLI / SLO / Error Budget
2.1 定义
SLI (Indicator): 怎么量 → 请求成功率 / P99 延迟 / 可用性
SLO (Objective): 目标值 → 99.9% 的请求 < 500ms
Error Budget: 预算 → 100% - SLO = 1 - 0.999 = 0.1%
2.2 好 SLI 的三原则
- 从用户视角度量(不是内部指标):用户感知的延迟/错误,不是服务器 CPU。
- 比率 + 阈值:如"成功请求 / 总请求"、"满足延迟阈值的比例"。
- 可被 SLO 直接衡量:SLI 的值必须能被查出来(有监控系统)。
2.3 常见 SLI
| 类型 | SLI 例子 |
|---|---|
| 可用性 | 成功请求 / 总请求 ≥ 99.9% |
| 延迟 | P95 响应 < 500ms(5 分钟内) |
| 吞吐 | 每秒处理请求 ≥ X |
| 持久性 | 数据不丢失 ≥ 99.999% |
| 新鲜度 | 数据延迟 < 60s |
2.4 SLO 设计:目标怎么定
- 看用户期望 + 业务成本,不是"越高越好"。
- 3 个九(99.9%):月停机 43 分钟;4 个九:4.3 分钟;5 个九:26 秒。
- 目标越高,成本和运维负担指数上升。定 99.9% 还是 99.95%,取决于用户是否真的在意那 0.05%。
2.5 Error Budget 的三种用法
1. 发布闸门: 预算用完 → 停止发布高风险变更 (保护稳定性)
2. 风险定价: 预算还有 → 可以冒险发布 (加速迭代)
3. 优先级: 预算快耗尽 → 把开发资源投到可靠性 (SLO 是待办优先级工具)
note
错误预算把"可靠性"从抽象的愿望变成可消耗的资源。就像团队有 43 分钟/月的"容错额度"——烧完就停止变更,回血了就恢复发布。这让"稳不稳"成为可量化、可决策的对象,而不是吵架。
2.6 告警:Burn Rate
| Burn Rate | 时间窗 | 告警级别 | 含义 |
|---|---|---|---|
| 1× | 30 天 | 无 | 正好用完预算 |
| 2× | 15 天 | 慢速告警 | 过半预算 |
| 14.4× | 2 小时 | 快速告警(严重) | 2 小时内烧完 1 个月预算 |
快速告警条件: 2h 内 burn rate ≥ 14.4 (14.4% 预算在 2h 消耗)
慢速告警条件: 24h 内 burn rate ≥ 3
三、容量规划
3.1 为什么要做
- 没容量 → 高峰期雪崩。
- 过度容量 → 浪费钱。
- 目标:在成本与风险间,预测并预留。
3.2 方法
1. 数据收集: 现有 QPS / 存储 / CPU 使用趋势
2. 趋势外推: 线性/指数增长曲线
3. 预测模型: 业务季节性 (双11/黑五/开学季)
4. 缓冲: 预留 30-50% (应对突发 + 发布后流量变化)
5. 验证: 压测 (locust/k6) 确认瓶颈
3.3 关键指标
| 指标 | 看什么 |
|---|---|
| 峰值 vs 均值 | 尖峰是否吃满 |
| 资源利用率 | CPU/内存 长期 > 70-80% 预警 |
| 饱和度 | 连接池/队列/磁盘 IO 是否到顶 |
| 增长趋势 | 周环比/月环比 |
3.4 扩缩容策略
| 方式 | 说明 |
|---|---|
| 手动扩容 | 有预见性,但慢 |
| 定时伸缩 | 已知高峰(业务周期性) |
| HPA(K8s) | 按 CPU/内存/自定义指标自动扩缩 |
| 预测式扩缩 | 基于历史趋势提前扩容 |
| 容量套餐 | 云上买弹性(预留 + 按量) |
# K8s HPA: 按 CPU 自动扩缩
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: { name: myapp }
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target: { type: Utilization, averageUtilization: 70 }
四、变更管理
4.1 原则:变更 = 事故的最大来源
统计上,生产事故的最大来源是变更(发布、配置改动、迁移)。SRE 的重点不是"别变",而是让变更可控。
4.2 变更的四个控制点
1. 小步: 每次变更小 (少 commit / 少配置) → 定位容易
2. 渐进: 金丝雀/灰度 → 先 5% 后全量
3. 可回滚: 每个变更都要有回滚计划 (发布前就想好)
4. 观察: 发布后 10-30 分钟盯指标, 异常立刻回滚
4.3 发布窗口(Change Window)
- 高风险变更选低流量时段(业务低谷)。
- 但"强制窗口"也会拖慢迭代 → 现代 SRE 更倾向"随时小步 + 自动化回滚"而非"每周一次大窗口"。
- 权衡:成熟团队 = 高频小变更(每次风险低)+ 强自动回滚;不成熟 = 低频大变更 + 长窗口。
4.4 配置变更风险
- 配置改动比代码改动更难回滚(没版本/没测试)。
- 方案:配置也走版本控制(GitOps)、配置变更也可灰度(feature flag)、配置有默认值向后兼容。
4.5 特征开关(Feature Flag)
- 让"发布代码"与"启用功能"分离。
- 新功能默认关 → 出问题只关 flag,不用回滚代码。
- 这是"发布风险降到最低"的核心工具之一。
五、事件响应(Incident Response)
5.1 生命周期
发现 → 响应/分级 → 缓解 → 解决 → 复盘(Postmortem)
5.2 分级(Severity)
| 级别 | 影响 | 响应时间 |
|---|---|---|
| SEV1 | 核心功能全挂 / 大规模用户不可用 / 数据丢失 | 立即 |
| SEV2 | 部分功能异常 / 部分用户受影响 | 30 分钟内 |
| SEV3 | 小范围 / 低影响 | 工作日内 |
| SEV4 | 无明显用户影响 | 排期处理 |
5.3 响应流程
1. 确认: 告警 → 确认是不是真的 (不是误报)
2. 宣布: 宣布 incident, 指定 owner, 拉群
3. 缓解优先于根因: 先止血 (回滚/降级/扩容), 别现场改代码!
4. 缓解手段 (回滚 / 切流量 / 禁缓存 / 扩容)
5. 验证缓解生效 (指标回落)
6. 复盘: 不追责, 找系统根因 + 改进项
warning
事件中最重要的原则:先止血,后查根因。在事故现场"顺手修 bug"是大忌——第一优先是恢复服务(回滚/降级),根因留到复盘。
5.4 Postmortem(复盘)
复盘的三要素:
- 不追责(Blame-free):目的找系统问题,不是找责任人。
- 根因分析:用"5 Why" 挖到系统/流程根因,不停在表面。
- 行动项:每条根因对应可验证的改进(SLO、告警、自动化、架构)。
复盘模板:
- 摘要 (发生了什么, 影响多大)
- 时间线 (何时发现/响应/缓解)
- 根因 (为什么, 5 Why)
- 为什么没被及时发现 (监控/告警缺口)
- 为什么没被自动缓解 (自动化缺口)
- 行动项 (每条带 owner + 截止日)
六、生产就绪(Production Readiness)
6.1 生产就绪清单(上线前必须)
[ ] SLI/SLO 已定义, 监控已配
[ ] 告警已接 (带 runbook)
[ ] 日志结构化, 可关联 trace_id
[ ] 容量已估算, 有扩缩容机制
[ ] 发布流程: 金丝雀 + 自动回滚
[ ] 回滚演练过
[ ] 备份 + 恢复演练过 (重要数据!)
[ ] 安全: 最小权限, 密钥外部管理, 依赖扫描
[ ] 文档: runbook, 架构图, 联系人
[ ] 失败注入/混沌测试 (可选但推荐)
6.2 混沌工程(Chaos Engineering)
- 主动注入故障(杀 pod / 断网 / 延迟)验证系统韧性。
- 工具:Chaos Mesh、Litmus、Gremlin。
- 原则:先在生产前(staging)验证,小范围开始。
6.3 无值班时怎么办(小团队)
- 没有专职 SRE → 用自动化兜底:自动回滚、自动扩缩、自助 runbook、异常自动降级。
- 把"靠人盯"降级为"靠系统兜底 + 人只在 SEV1 被叫醒"。
七、SRE 的自动化思维
7.1 凡事都该自动化
| 人肉操作 | 自动化替代 |
|---|---|
| 手工部署 | GitOps + 自动发布 |
| 手工扩容 | HPA + 预测扩缩 |
| 手工回滚 | 自动回滚(发布失败自动退) |
| 手工排查 | runbook + 一键诊断脚本 |
| 手动恢复 | 自愈(liveness + restart) |
7.2 自动化优先级
高价值: 发布 / 回滚 / 扩缩 / 恢复 (出事最需要)
中价值: 监控告警 / 容量预测
低价值: 一次性诊断
tip
自动化的目标不是"减少人手",是减少 MTTR(平均修复时间)。每次事件后问"这段能不能自动化"——自动回滚、自动扩缩、自动切流量,这些是降低 MTTR 的核心。
八、结束 + 速查表
tip
一页快速唤回:
- SRE = 可度量的可靠性:稳定 × 速度平衡,50% 时间做工程化。
- SLI(怎么量)/ SLO(目标)/ Error Budget(100%-SLO = 容错额度)。
- 3 个九:月停 43min;4 个九:4.3min;目标别盲目往高定。
- 错误预算三用法:发布闸门 / 风险定价 / 优先级工具。
- Burn Rate:14.4×(2h)= 严重告警;预算内波动不告警。
- 容量:趋势 + 季节性 + 30-50% 缓冲 + 压测;HPA 自动扩缩。
- 变更 = 事故主源:小步 / 渐进 / 可回滚 / 观察;feature flag 分离发布与启用。
- 事件响应:先止血(回滚/降级)后查根因;复盘不追责。
- 生产就绪:SLO+告警+日志+回滚演练+备份恢复+安全。
- 自动化目标:降 MTTR,不是减人手。
回主目录: 工程化实践轴 README.