跳过正文
SRE 核心理念:从运维思维到可靠性工程

SRE 核心理念:从运维思维到可靠性工程

·679 字·4 分钟·
目录
SRE 实战手册 - 这篇文章属于一个选集。
§ : 本文

我在转型 SRE 之前做了三年传统运维。那时候的日常是:写工单、执行部署、接到告警、半夜爬起来重启服务、第二天继续写工单。系统越来越复杂,告警越来越多,人越来越累,但没有人问"为什么会这样"。

SRE 的转型不是换了个 title,而是换了一套思考框架——从"保证系统不挂"到"用工程化的方法管理可靠性"。这篇文章把我对 SRE 核心理念的理解系统整理出来,希望对同样在路上的人有帮助。

运维工程师 vs SRE:根本区别
#

最表面的区别是:SRE 写代码,运维不一定写。但这不是本质。

本质区别在于对"可靠性"的认知不同

传统运维的潜意识是:系统不能挂,挂了就是我的失职。这会导致几个问题:

  • 过度保守:变更窗口越来越少,“不出事"比"快速迭代"优先级更高
  • 救火文化:花大量时间处理线上问题,没有时间做系统改进
  • 人作为屏障:人肉拦截风险,流程越堆越多,但系统本质没有变得更健壮

SRE 的认知是:系统总会出故障,问题不是"如何避免所有故障”,而是"如何在可接受的故障率内快速迭代"

Google SRE 团队有一句话我觉得很精准:

“Hope is not a strategy.”

光靠祈祷不出事、靠人工检查来保证质量,不是工程方法。SRE 是把可靠性当成一个工程问题来解决。

Error Budget:可靠性不是越高越好
#

这是 SRE 最核心、也最反直觉的概念。

假设你的 SLO(服务等级目标)是 99.9% 的可用性,那么一个月(43200 分钟)的允许故障时间是:

43200 × (1 - 0.999) = 43.2 分钟

这 43.2 分钟就是你的 Error Budget(错误预算)

Error Budget 的逻辑是: 如果用户对 99.9% 可用性感到满意,那么额外追求 99.99% 对用户并没有额外价值,但会大幅增加工程成本(变更更谨慎、迭代更慢)。

Error Budget 的消耗不只是故障,还包括:

  • 计划内的维护窗口
  • 发布失败导致的降级
  • 实验性功能的不稳定

Error Budget 怎么指导决策:

状态策略
Budget 充裕(消耗 < 50%)可以加快发版节奏,尝试更多实验性变更
Budget 告急(消耗 > 80%)暂停非关键发版,优先做可靠性改进
Budget 耗尽冻结变更,直到下个周期预算恢复

这个机制的妙处在于:它让开发团队和 SRE 团队有了共同的目标。开发不能说"SRE 在阻碍我们发版",因为大家都看着同一个 Error Budget 表盘。Budget 有的时候开快,Budget 没了大家一起踩刹车。

SLI / SLO / SLA:层次关系和制定方法
#

这三个缩写经常被混用,但它们有明确的层次关系。

SLI(Service Level Indicator,服务等级指标)
#

SLI 是你用来度量服务质量的具体指标,必须是可度量的数字。

常用 SLI 类型:

可用性(Availability):
  good_requests / total_requests × 100%
  好请求 = HTTP 状态码 < 500 且延迟 < 2s

延迟(Latency):
  P99 响应时间(第99百分位)
  P50 响应时间(中位数)

错误率(Error Rate):
  5xx_requests / total_requests × 100%

吞吐量(Throughput):
  RPS(每秒请求数)

饱和度(Saturation):
  CPU 使用率 P99
  内存使用率

好的 SLI 应该是从用户视角定义的,而不是从系统内部指标定义的。“CPU < 80%“不是好 SLI,“P99 响应时间 < 500ms"才是。

SLO(Service Level Objective,服务等级目标)
#

SLO 是 SLI 的目标值,通常有时间窗口:

可用性 SLO: 99.9%(过去28天滚动窗口)
延迟 SLO: P99 响应时间 < 500ms(过去1小时)
错误率 SLO: < 0.1%(过去24小时)

制定 SLO 的原则:

  1. 从用户能接受的级别出发,而不是从当前系统能达到的级别出发。问题是:“用户在什么情况下会觉得服务不满意?”

  2. 比当前实际水平稍低一点,给改动和实验留空间。如果现在稳定跑在 99.95%,设 SLO 为 99.9% 而不是 99.99%。

  3. 从宽松开始,逐步收紧。SLO 设太紧会让整个团队陷入焦虑,SLO 设太松没有意义。先跑 3 个月,看实际水平,再调整。

  4. 不是所有服务都需要 99.99%。内部管理后台可能 99.5% 就够了;支付服务可能需要 99.99%。SLO 应该反映服务对用户的重要性。

SLA(Service Level Agreement,服务等级协议)
#

SLA 是对外承诺,通常带有违约赔偿条款。SLA 通常比 SLO 宽松,因为 SLO 是内部目标,SLA 是外部合同。

关系:SLO > SLA,留有缓冲。如果内部 SLO 是 99.9%,对外 SLA 可能承诺 99.5%。

Toil:识别并消除琐事
#

Toil(Pronunciation: /tɔɪl/)是 SRE 文化中的核心概念,指那些手动的、重复的、可以自动化但还没被自动化的运维工作

Toil 的特征:

  • 手动操作(需要人参与执行)
  • 重复性(每次部署都要执行同样的步骤)
  • 没有持久价值(做完这次,下次还要做)
  • 随系统规模线性增长(服务越多,手动操作越多)

典型的 Toil 举例:

  • 每次发版都要手动在 Slack 发通知
  • 收到告警后,手动执行一堆固定的排查命令
  • 每周手动生成一份容量报告
  • 新员工入职手动创建账号、配置权限
  • 定期手动清理日志或临时文件

如何衡量 Toil: Google 的建议是 Toil 占工作时间不超过 50%,理想在 30% 以下。如果超过 50%,团队就在"生产力债务"上越陷越深。

消除 Toil 的思路:

识别 → 量化(花了多少时间)→ 优先级排序(频率 × 时间成本)→ 自动化

一个实际例子:我们以前每次数据库慢查询告警都要手动去看 EXPLAIN 输出,判断是不是索引问题,大概每次花 15-20 分钟。后来写了个脚本,告警触发时自动执行 EXPLAIN ANALYZE,把输出和历史对比后附在告警消息里,人只需要看结论。每月节省约 3 小时。

On-call:告警疲劳的克星
#

好的 On-call 制度不是"7×24 随时待命”,而是确保被呼叫的人能高效处理问题,同时不被耗尽

告警质量比告警数量更重要
#

告警疲劳(Alert Fatigue)是 On-call 最大的敌人。当告警太多、误报太多,On-call 工程师会开始忽略告警——这比没有告警更危险。

每一条告警都应该满足:

  1. 可操作(Actionable):收到这条告警,我知道要做什么
  2. 紧迫(Urgent):现在不处理会影响用户
  3. 准确(Accurate):不是误报

定期做告警审计:

# 列出最近 30 天触发次数最多的告警
# 对于误报率高的告警:调整阈值、修复根因或直接删掉
# 对于从不触发的告警:可能阈值设得太高,失去了预警作用

On-call 轮班设计原则
#

  • 轮班而不是固定值班:没有人应该永远是那个被叫醒的人。每个人轮流承担 On-call,也是让团队理解系统痛点的最好方式。

  • 一周轮换一次:太短(一天)切换成本高;太长(一个月)把人榨干。

  • Primary + Secondary 双层:Primary 先响应,超时(比如 15 分钟)自动升级到 Secondary,避免 Primary 联系不上的情况。

  • 避免 Off-hours 告警打扰:P3/P4 级别的告警在工作时间处理,只有 P1/P2 才在深夜叫醒人。

  • On-call 补偿:被叫醒的夜班时间应该折算成工作时间,否则长期下去会造成 Burnout。

响应时间目标
#

P1(服务完全不可用):5分钟内响应,30分钟内恢复或降级
P2(核心功能受损):15分钟内响应,2小时内恢复
P3(部分功能降级):1小时内响应,工作时间内恢复
P4(轻微问题):下个工作日处理

故障复盘:Postmortem 文化
#

故障复盘(Postmortem)是 SRE 文化中最有价值的实践之一。好的 Postmortem 不是"找凶手”,而是"找系统问题”。

无指责文化(Blameless Culture)
#

这是 Postmortem 有效运作的前提。出故障时,人为错误(比如误删数据库、改错配置)几乎都是系统问题的表现:

  • 为什么一个人能直接操作生产数据库而没有审核?(权限问题)
  • 为什么一条错误的配置能直接生效而没有验证?(变更流程问题)
  • 为什么告警 30 分钟后才触发?(监控问题)

如果 Postmortem 变成批斗会,工程师下次出事就会隐瞒信息、推卸责任,整个团队学不到任何东西。

Postmortem 模板
#

## 故障摘要
- 时间线:发生时间 → 检测到时间 → 恢复时间
- 影响范围:受影响的服务、用户数量、错误率
- 严重程度:P1/P2/P3

## 时间线(详细)
| 时间 | 事件 |
|------|------|
| 14:32 | 监控告警触发,API 错误率从 0.1% 跳升至 15% |
| 14:35 | On-call 工程师响应 |
| 14:48 | 定位到是数据库连接池耗尽 |
| 15:01 | 重启应用实例,错误率恢复正常 |

## 根本原因(Root Cause)
连接池配置的 max_connections=20,但高峰期并发请求达到 50,
导致连接排队超时。代码上线时没有做容量测试。

## 触发因素 vs 根本原因
触发因素:下午高峰期流量增加 40%(某个营销活动)
根本原因:连接池配置没有根据实际流量压测,且没有监控连接池使用率

## 影响评估
- 持续时间:29 分钟
- 受影响用户:约 3200 个活跃用户
- 错误率峰值:23%
- Error Budget 消耗:18.5 分钟(43.2 分钟月预算)

## 改进行动(Action Items)
| 行动 | 负责人 | 截止日期 |
|------|--------|----------|
| 调整连接池配置为动态扩展 | 张三 | 本周五 |
| 添加连接池使用率监控告警(阈值80%) | 李四 | 本周三 |
| 针对高峰期场景建立压测流程 | 王五 | 下月15日 |
| 在上线检查清单中加入容量测试项 | 张三 | 本周五 |

## 优点(哪里做得好)
- 告警触发及时(故障后3分钟),远优于用户投诉
- On-call 工程师快速响应并准确定位根因

做 Postmortem 的时机
#

  • P1/P2 故障:必须做,通常在故障后 48 小时内完成
  • P3 故障:选择性做,尤其是反复出现的问题
  • 差点出事但被及时发现的情况(Near Miss):也值得做,成本最低、收益最高

SRE 与开发团队的协作
#

最差的 SRE/运维模式是:开发扔过来一个部署包,SRE 负责部署和维护,遇到问题互相推诿。

SRE 的定位应该是赋能者,而不是守门人

生产准入评审(Production Readiness Review)
#

新服务上线前,SRE 与开发一起做 PRR,检查清单类似:

## 可观测性
- [ ] 有结构化日志,包含 trace_id
- [ ] 有 Prometheus 指标端点 (/metrics)
- [ ] 有存活探针 (livenessProbe) 和就绪探针 (readinessProbe)
- [ ] 关键业务路径有 SLI 指标

## 可靠性
- [ ] 做过容量规划(预期 RPS、资源请求/限制设置合理)
- [ ] 有健康检查接口 (/health)
- [ ] 有优雅关闭逻辑(SIGTERM 后等待在途请求完成)
- [ ] 有限流或熔断机制(外部依赖挂了会怎样)

## 部署
- [ ] 支持滚动更新(无状态或做了会话保持)
- [ ] 有回滚方案(镜像 tag 可回滚)
- [ ] 数据库变更有迁移脚本,变更是向后兼容的

## 告警
- [ ] 有对应的 SLO 和告警规则
- [ ] 告警消息包含排查指引链接

这不是审批卡点,而是在上线前帮开发团队发现遗漏的地方。

Embedded SRE vs Consulting SRE
#

两种常见合作模式:

  • Embedded SRE:SRE 直接嵌入业务团队,深度参与日常开发,适合服务复杂度高、SRE 资源充足的情况。
  • Consulting SRE:SRE 作为独立平台团队,提供工具和最佳实践,由业务团队自行负责可靠性。适合 SRE 资源有限的情况。

大多数中小型公司是后者。关键是要避免"没有人对可靠性负责"的真空地带——开发说"那是运维的事",运维说"代码是开发写的"。

从传统运维转型 SRE 的实际路径
#

转型不是一夜之间的事,我见过比较实际的路径是:

第一阶段:建立度量体系(3-6个月)

先把 SLI 测量建起来。你不能改善你不能度量的东西。

  • 接入 Prometheus + Grafana
  • 为核心服务定义 3-5 个 SLI
  • 建立基础告警(不求完美,先跑起来)

第二阶段:SLO 试行(3-6个月)

  • 选 1-2 个核心服务,制定 SLO
  • 跑一个季度,看实际水平
  • 建立 Error Budget 报告机制(哪怕是手动生成)

第三阶段:消除 Toil(持续进行)

  • 统计 Toil 占用的时间
  • 选 ROI 最高的自动化(频率最高 × 时间最长)
  • 固定每个 Sprint 投入 20% 时间做自动化

第四阶段:建立工程文化

  • 推行 Postmortem,确保无指责文化落地
  • 规范 On-call 流程,引入 告警评审
  • 让开发团队参与 On-call(哪怕只是观察),建立共同责任感

转型过程中最大的阻力通常不是技术,而是文化——管理层的"不出事就好"心态、开发团队的"稳定性不是我的事"认知。这需要用数据说话:Error Budget 耗尽、Toil 消耗时间报告,这些是推动文化变革最有力的工具。

总结
#

SRE 一句话:把可靠性当工程问题做,不要靠堆人。

落到手上就这四件事:

  • Error Budget 把"可靠性 vs 迭代速度"的矛盾摆到明面上
  • SLI/SLO 把"系统好不好用"从主观判断变成数据
  • Toil 要系统性消掉,别让人长期当脚本跑
  • Postmortem 把每次故障变成组织记忆

这套东西不是大厂专利,三四个人的小团队一样能用——哪怕只有一张 SLO 表 + 一个简陋的 Error Budget + 写 postmortem 的习惯,对系统的掌控感就完全不一样。

Wenzhuo Huang
作者
Wenzhuo Huang
搞运维的工程师,写代码的运维人。专注 Kubernetes、AWS、GitOps 与基础设施可靠性。这个博客既是我的技术笔记本,也是我踩过的坑的受害者档案。
SRE 实战手册 - 这篇文章属于一个选集。
§ : 本文

相关文章

故障排查方法论:从现象到根因

·622 字·3 分钟
好的排查不靠直觉,靠方法。这篇文章总结了我在多次生产故障中提炼出的排查框架:从时间线构建到假设优先级,再到认知陷阱的识别与规避。

SRE 实践心得:从运维到 SRE 的思维转变

·531 字·3 分钟
SRE 不是换了个头衔的运维,而是一套用软件工程思维解决可靠性问题的方法论。这篇文章记录了我在实践过程中最有感触的几个转变。

Kubernetes 集群升级策略:零停机升级的完整实践指南

·855 字·5 分钟
K8s 集群升级听起来简单,实际操作中坑很多:API 弃用导致的 Helm 失败、Admission Webhook 拦截升级流量、PDB 配置不当导致服务中断。这篇文章从真实的升级经验出发,给出一套可复用的零停机升级方案。