9.1 站点可靠性工程
概述与动机
站点可靠性工程(SRE)把软件工程实践应用到生产系统的运行当中。SRE 不再把运维当作与开发相分离、由工单驱动的手工劳动,而是把可靠性当作一个工程问题,用代码、度量和明确的服务目标去解决它。这个由 Google 推广、如今已广为流传的核心理念很简单:维持系统运转的人,应当把大部分时间用于构建自动化和改进系统,而不是一次又一次地手工扑灭同样的故障。
对大型团队而言,这一点之所以重要,是因为规模同时抬高了可靠性的价值,也抬高了做错这件事的代价。当一项服务支撑着数百万用户或数千个内部使用者时,一小时的停机就意味着收入损失、交易失败和信任受损。在少数几台服务器上行得通的手工运维方式,一旦面对数百个服务和持续部署,就会土崩瓦解。SRE 为可靠性提供了一套共同语言,一种把”发布新功能”与”保持系统稳定”之间的取舍摆到台面上明说的方式,以及一种能在众多团队之间始终如一地守住这条底线的方法。
企业和政府场景又为此增添了更多分量。银行、医疗保健和公共服务等受监管行业,往往背负着法律或合同层面的可用性承诺、审计要求,以及对影响公民或安全的服务中断近乎零容忍的态度。政府数字服务也日益公开发布自己的可靠性目标和绩效数据。SRE 为你提供了一套严谨、以证据为基础的方法,用来定义”足够可靠”究竟意味着什么、诚实地度量它,并用数据而非观点,向领导层和监督机构捍卫工程优先级的选择。
另见: 第 9.2 章(可观测性与监控)、第 9.3 章(事件管理),以及第 3.5 章(可扩展性、性能与韧性)。
关键原则
- 可靠性是最重要的功能。 一个不能正常工作的系统,无论拥有多少功能都毫无价值,但完美的可靠性既不可实现,也不值得为之付出的成本。
- 用可度量的目标来定义可靠性。 服务水平指标(SLI)、服务水平目标(SLO)和服务水平协议(SLA),把模糊的期望变成了人人都能认同的数字。
- 100% 是一个错误的目标。 用户无法分辨一个非常可靠的系统和一个完美可靠的系统之间的区别,因此应当以”足够可靠”为目标,把剩余的预算花在提升速度上。
- 错误预算能让各方利益保持一致。 SLO 与 100% 之间的差距,是开发者和运维人员共同分享的风险预算,它用算术取代了争论。
- 琐事(toil)是大敌。 重复的、手工的、可自动化的运维工作应当被度量、设置上限,并被系统性地消除。
- 有意识地实施自动化。 自动化是一个小团队能够运维一个大系统的方式;投资自动化是一项一等公民级别的工程活动。
- 无责学习。 故障被当作改进系统和流程的机会,而不是惩罚个人的理由。
建议
有意识地定义 SLI、SLO 和 SLA
从用户的视角出发。服务水平指标(SLI) 是对服务行为的量化度量,例如在 300 毫秒内得到响应的请求比例,或成功响应所占的比例。挑选少量真正能反映用户满意度的 SLI:可用性、延迟、正确性和数据新鲜度是常见的几种。服务水平目标(SLO) 是某个 SLI 的目标值或目标区间,例如”在滚动的 28 天窗口内,99.9% 的请求成功”。服务水平协议(SLA) 则是一份把承诺水平与后果(退款、违约金)挂钩的合同。要让你的 SLO 比 SLA 更严格,这样在真正违反承诺之前,你就能先收到预警。要公开你的 SLO,每季度进行审查,并把它们当作会随着你的认知而收紧或放宽的活文档来对待。
采用错误预算并切实执行
错误预算就是 100% minus the SLO。如果你的 SLO 是 99.9%,那么你在每个窗口期内的预算就是 0.1% 的不可靠度,大约相当于每月 43 分钟。要把它花在有计划的风险上:激进的发布、实验,以及受控的故障测试。当预算充裕时,团队可以快速发布。当预算耗尽时,既定政策应当自动把优先级转向可靠性工作,并暂停有风险的变更,直至系统恢复。错误预算的力量在于,你是提前就它达成一致的,因此当服务中断真正发生时,它就把情绪和政治因素从那一刻中抽离了出来。
度量并减少琐事
琐事是指那种手工的、重复的、可自动化的、战术性的、且会随系统一同增长的运维工作。要追踪 SRE 花在琐事上的时间百分比,并设定一个上限()通常在 50% 左右()从而确保至少一半的工程时间投入到能够持久发挥作用的改进上。要维护一份”减少琐事”项目的待办清单,按”频率乘以成本”排定优先级,并把消灭一项反复出现的任务,当作和发布一项新功能一样值得庆祝的事情。一项自动化强制要求能让这一点变得明确:任何被执行次数超过某个设定阈值的手工流程,都会成为自动化或自助式工具的候选对象。
规划容量并预测需求
依据历史趋势、既定发布计划和业务预测,为你预期的负载建模。要把有机增长预测与一次性事件(例如营销活动、报税截止日期,或在政府场景中尤为重要的福利登记期)结合起来考虑。要在峰值之上保留余量,通过压力测试来检验你的假设,并在力所能及之处实现扩容自动化,同时对重大承诺保留一份经人工审核的容量计划。要追踪资源调配的提前期,这样短缺就永远不会让你措手不及。
把可靠性当作一项有真实成本的功能来对待
每增加一个”9”的可用性,通常都比前一个”9”要花费多得多的冗余、测试和运维复杂度成本。要把”9”的成本明确摆出来,让产品负责人在充分知情的情况下选择目标。要为优雅降级而设计,这样局部故障带来的是服务能力的降低,而不是彻底的服务中断。要按 SLO 的要求、而不是在所有组件上平均分配的方式,来投入冗余和故障切换能力。
选择一种 SRE 组织模式
没有唯一正确的结构。一支中心化的 SRE 团队能带来一致性、深厚的专业知识和共享工具,但也可能沦为瓶颈,或者变成别人问题的倾倒场。嵌入式模式把 SRE 安置在产品团队内部以实现紧密协作,但也存在不一致和被孤立的风险。许多大型组织采用一种混合模式:一个中心化的平台与标准团队,加上嵌入式的可靠性工程师,并配有一套清晰的合作模型,明确规定一项服务需要满足什么条件才能获得 SRE 支持,以及它首先必须跨过怎样的生产就绪门槛。
权衡:利与弊
| 决策 | 优点 | 缺点 |
|---|---|---|
| 严格的 SLO(更多个 9) | 用户信任度更高,能满足合同要求 | 成本上升,功能交付变慢 |
| 宽松的 SLO(更少个 9) | 发布更快,成本更低 | 存在用户流失和 SLA 违约金的风险 |
| 中心化 SRE | 一致性、共享的专业知识 | 容易成为瓶颈,与产品团队有距离 |
| 嵌入式 SRE | 紧密协作、了解业务背景 | 一致性差,招聘配置困难 |
| 大力投入自动化 | 可扩展,减少琐事 | 前期成本高,自动化本身也可能出故障 |
可靠性工程真正关心的,是如何明智地花费有限的资源。为一个用户根本感知不到的额外的”9”而拼命,会浪费本可以用来投入功能开发或降低价格的资金。反过来,对一个故障会造成真实伤害的系统投入不足,那就是失职。错误预算这套框架存在的意义,正是把这种取舍变得可见、可协商,而不是隐而不宣、争论不休。组织模式方面的取舍同样真实存在:正确答案取决于公司规模、工程成熟度,以及你各项服务的统一程度。
需要与团队讨论的问题
哪一个具体的 SLI 真正反映了用户的实际感受,你能否证明它不是一个虚荣指标? 选错了指标,仪表盘可能一片绿色,而用户却在受苦,这正是本章所警示的”虚荣 SLI”陷阱。把真实数据带到讨论中来:从一条真实的请求路径(登录到仪表盘、结账到确认)而不是服务器 CPU 或后端健康检查中,去测量同一条用户旅程。对大型团队而言,一个糟糕的 SLI 会不断扩散:数十个服务继承了它,告警在错误的地方触发,错误预算也随之失去意义。在企业和政府场景中,一份 SLA 往往牵涉退款或公民影响,你的 SLI 就是你要向审计方捍卫的证据,因此它必须能够直接追溯到用户可感知的成功。如果你无法从这个数字画出一条线连到用户的真实体验,那就该换掉这个数字。
在你的 SRE 团队接手某项服务的待命职责之前,这项服务必须证明什么,又是谁有权说”不”? 没有生产就绪门槛,中心化的 SRE 团队就会沦为每一个不稳定服务的倾倒场,被别人的技术债务淹没。要把准入标准写下来:一个自有的 SLO、可用的操作手册、可执行的告警、容量余量,以及一条经过验证的部署与回滚路径。对大型组织而言,正是这套合作模型让可靠性团队免于沦为拖慢所有人的瓶颈。在受监管的场景中,就绪评审同时也是一项可以向监督机构展示的控制措施。要决定谁有权拒绝某项服务的接入,因为一条没人执行的门槛根本不算门槛,而这个答案将决定 SRE 是能够扩展壮大,还是被继承来的痛苦所拖垮。
对于你最大的那个可预测的峰值,你会提前多久开始预先配置资源,你知道自己的资源调配提前期是多久吗? 假定云的弹性是即时且无限的,恰恰会在最关键的那些峰值期间招致短缺,而那些峰值时刻(报税截止日期、登记窗口期、促销活动)正是故障最显眼、代价也最高昂的时刻。把这些数字带来讨论:历史峰值负载、预测增长率、你进行压力测试所依据的倍数,以及获取大规模预留容量或专用实例的真实提前期。对于政府的季节性服务而言,峰值可能达到正常负载的数倍,且在政治上绝不容有任何闪失,因此提前数周预先配置资源,胜过寄希望于自动扩容能够及时跟上。答案应当落地为一份具体的日程表:什么时候做压力测试,什么时候锁定容量,以及谁拥有最终决定权。
当你的错误预算耗尽时,实际会发生什么,又是谁有资格去执行这项政策? 一个在耗尽时从未被真正执行过的错误预算,只是一件装饰品,而服务中断的那一刻,恰恰是从零开始协商政策的最糟糕时机。这里的对立力量是真实存在的:一次既定的发布、一个收入截止日期,或一次公开宣布,都会对”冻结有风险变更”这件事施加强大的压力。把燃尽率数据、预先商定好的政策文本,以及最近几次预算被突破时的记录都带来,这样你就能看清冻结措施是否真的被执行了。对大型团队而言,预算只有在每个小组都遵循同样的执行标准时,才能真正统一各方的激励,因此要提前决定谁有权签字批准例外情况,以及这种例外将如何被记录下来。在 SLA 牵涉违约金或公民影响的企业和政府场景中,这条例外记录会成为一份审计证据,因此现在就应当指定负责人,而不是等预算已经耗尽了才临时决定。
你的 SRE 团队每周有多大比例的时间花在琐事上,这是一个被测量出来的数字,还是仅凭感觉? 没有人统计的琐事会悄悄膨胀,直到团队把全部时间都花在救火上,完全没有时间去构建持久的改进()而这正是 SRE 存在的意义所要摆脱的陷阱。这里的张力在于,度量琐事本身也是一项工作,而处于截止日期压力下的工程师会抗拒记录自己的时间都花在了哪里。带上一份诚实的样本:一到两周内按照一个共同的琐事定义(手工的、重复的、可自动化的、战术性的、随系统一同增长)追踪出来的时间,再加上一份按”频率乘以成本”排序的自动化项目待办清单。对大型组织而言,50% 的上限只有在按团队逐一上报并落实的情况下才有意义,因此要商定好由谁来审查这个数字,以及当某个团队突破上限时会发生什么。在受监管和政府场景中,给琐事设置上限,能把稀缺的专业人才解放出来,投入到被手工运维挤占的控制与审计工作中去,因此应当把琐事这个数字,当作一个领导层应当看到的产能信号。
你目前运行的是哪一种 SRE 组织模式,什么样的证据能告诉你它已经不再适用? 中心化团队能带来一致性和共享工具,但也可能沦为瓶颈;嵌入式模式能带来业务背景知识,但会逐渐走向不一致;大多数大型组织最终采用的混合模式,则需要一套清晰的合作模型,否则就会继承两种模式各自的弱点。把揭示压力的各项信号带来:服务等待 SRE 支持需要多长时间、各团队之间的可靠性实践差异有多大,以及嵌入式工程师是否感觉自己被隔绝在专业社群之外。正确答案取决于公司规模、工程成熟度,以及你各项服务的统一程度,因此应当随着这些因素的变化而重新审视它,而不是把最初的选择当作一成不变的定论。对于拥有众多团队、且对统一性有严格要求的企业或政府机构而言,一个中心化的标准与平台团队加上嵌入式可靠性工程师,通常能够在一致性与本地业务背景之间取得平衡()但前提是合作模型和生产就绪门槛都被明文记录下来,并且有人对其负责。
行业视角
创业公司。 团队只有几名工程师,也没有余力组建专职的可靠性团队,应当在最重要的那条用户旅程上选定唯一一个 SLO,并让待命职责由全体团队成员共同分担。要依靠云服务商的托管服务和内置监控,而不是自建可观测性基础设施,并把简短的事后总结写在共享文档里,让修复措施真正落地。在这个阶段,速度比流程更重要:一个你真正会去执行的宽松 SLO,胜过一个没人关注的精心设计的 SLO。
小型企业。 没有专职人员来运营可靠性工作,应把它当作一门通过所用平台”买入”的学科:托管的正常运行时间监控、托管数据库和状态页工具,而不是定制化的技术栈。设定一到两个与能带来收入的交易紧密相关的 SLO,并诚实地判断哪些故障会让你失去一个客户。在购买比自建更划算的地方购买韧性能力,并把运维负担控制在现有工程师能够在完成功能开发的同时兼顾的水平上。
企业。 挑战在于跨众多团队的一致性:一套共享的 SLO 词汇体系、一套通用的错误预算政策,以及一道每项服务在被 SRE 纳入待命范围之前都必须跨过的生产就绪门槛。一个中心化的平台与标准团队加上嵌入式的可靠性工程师,能在不沦为瓶颈的前提下保持实践的统一性,而治理层面则需要错误预算在各处都以同样的方式上报和执行。要为可观测性基础设施和自动化投入明确编列预算,并把可靠性当作一个拥有领导层可见指标的投资组合来管理。
政府。 公共服务往往背负着已公开的可用性目标、法定承诺和审计义务,因此 SLO 和错误预算方面的决策会成为你需要向监督机构捍卫的记录。采购规则可能会限制你能使用哪些监控和托管方案,而透明度方面的期望则会促使你在一个公开的状态仪表盘上发布可靠性数据。要为报税截止日期、福利登记窗口期等极端的季节性峰值提前数周做好规划,并维护一种无责的事后总结文化,让公开的故障推动系统改进,而不是引向对个人的问责。
示例
创业公司。 一家十人规模的创业公司运行着一个单一的 Web 应用,待命职责由三名工程师共同分担。它没有去组建一支负担不起的可靠性团队,而是选定了一个真正有意义的 SLO:登录到仪表盘这条流程的成功率达到 99.5%,且依据真实用户请求进行测量。当一个不稳定的第三方 API 开始蚕食这一预算时,团队用一个周五添加了重试和缓存机制,而不是继续发布下一个功能,随后在共享文档里写下了一份两段话的事后总结,让这个修复真正落地。
企业。 一家全球性的支付公司为其交易 API 设定了 99.99% 的可用性 SLO,这意味着每月大约有四分钟的错误预算。一个中心化的 SRE 平台团队负责共享的可观测性、事件处理工具和错误预算政策,而嵌入式的可靠性工程师则分布在各个产品团队内部工作。当一项新的欺诈检测功能在一周内耗掉了半个月的预算时,预先商定好的政策冻结了非关键性的发布,直至可靠性工作恢复出足够的余量。高管们对此毫无异议地接受了,因为他们早已提前批准了这项政策。
政府。 一个国家税务机关运行着一项在线申报服务,在年度截止日期前后会出现极端的季节性峰值。其 SRE 团队依据往年数据以及人口和政策变化来预测需求,以正常峰值的数倍进行压力测试,并提前数周预先配置好容量。面向公众的可用性和页面延迟 SLO 会公布在一个状态仪表盘上。一种无责的事后总结文化(审查故障是为了改进系统,而不是追究个人责任)加上一项自动化强制要求,正稳步削减着那些曾经在申报季主导一切的手工干预,让工作人员得以把精力投入到改进系统上,而不是在每个截止日期前疲于奔命地维护它。
商业论证:动机、投资回报率与总拥有成本
SRE 的回报来自三个方面:避免了停机、减少了运维人力,以及更快速而安全的交付。对一项大型服务而言,停机每小时可能造成数千到数百万计的收入损失、违约金和补救成本,因此即便是适度的可靠性提升,也能迅速收回一支团队的成本。琐事的减少,把反复发生的人力成本转化为一次性的自动化投入,因此总拥有成本会随着规模扩大而下降,而不是随之攀升。错误预算让业务方能够在可靠性状况良好时更快地发布,从而捕获那些过于谨慎的运维方式原本会白白放弃的功能价值。
采纳成本是真实存在的。SRE 需要熟练的工程师、可观测性基础设施,以及一种会与功能交付截止日期相竞争的文化变革。但不采纳它的成本,在规模扩大后会更高:无节制膨胀的运维人力、无法预测的服务中断、员工的职业倦怠与流失,以及难以量化却很容易切身体会到的声誉损害。要向领导层阐述这一论证,就把 SRE 塑造成一种具备可衡量回报的风险管理手段。呈现当前事件和手工运维所产生的成本、与业务承诺挂钩的 SLO 目标,以及二者预计能够实现的削减幅度。把论证的核心锚定在”错误预算是一项治理工具”这一点上,因为它为领导层提供了一个能够真正撬动”可靠性与速度”这一取舍的杠杆。
反模式与常见陷阱
- 把运维团队重新贴上 SRE 的标签。 只是给运维团队改了个名字,却没有给予其相应的工程时间、自动化强制要求和拒绝的权力,什么也不会改变。
- 以 100% 为目标。 追求完美的可靠性,会浪费金钱、拖慢交付,却换来用户根本感知不到的收益。
- 虚荣 SLI。 测量服务器 CPU 而不是用户可见的成功指标,会得到看起来不错、实际上用户却在受苦的数字。
- 没有约束力的错误预算。 一个在耗尽时从未被执行过的预算,只是一件装饰品。
- 不加测量的琐事。 如果你不追踪琐事,它就会悄悄吞噬团队,直到再也没有任何改进工作能够开展。
- 把 SRE 当作倾倒场。 没有就绪门槛、继承了每一个不稳定服务的中心化团队,会被别人的技术债务淹没。
- 忽视容量调配的提前期。 假定云的弹性是即时且无限的,会在最关键的那些峰值期间招致短缺。
成熟度模型
第 1 级,启动。 运维是手工且被动的。没有正式的 SLO,可靠性全凭个人观点,同样的事件反复发生,救火主导着一切。任何自动化都是偶然出现的,也没有人把可靠性当作一个工程问题来负责。
第 2 级,发展。 一些服务拥有基本的 SLI 和 SLO,以及初步的监控和告警,但各团队之间的实践差异很大。琐事已被认识到,却没有被度量,自动化是临时性的,事后总结也做得参差不齐。可靠性只在个别人推动的角落里有所改善,而不是因为组织提出了要求。
第 3 级,标准化。 SLI、SLO 和一套错误预算政策已被明文记录,并在各团队之间一致地执行。琐事被定义并被追踪,容量规划成为常规工作,一套带有生产就绪评审的 SRE 合作模型已经建立,自动化是一条有专门预算的工作线,而不是一个附带项目。可靠性实践被写了下来,并在整个组织范围内得到执行。
第 4 级,管理。 可靠性项目依据基线用数据加以度量和管控。错误预算燃尽率、琐事占比、SLO 达成率、平均恢复时间和资源调配提前期都作为指标被追踪,按固定节奏被审查,并被用来约束各团队实现自己的目标。预算被突破会触发既定的冻结措施,容量依据需求模型进行预测,每一次”是否放行”的决策都依据证据,而不是个人观点。
第 5 级,编排。 可靠性工程在整个组织范围内实现了集成,并被持续改进。错误预算政策实现了自动化,并在各处都得到遵守,大多数运维操作实现了自助化,容量被主动地预先配置,可靠性数据驱动着速度与稳定性之间的自适应取舍。组织会随着业务和风险态势的变化,习惯性地重新界定 SLO 的范围、消除琐事,并重新平衡可靠性方面的投入。
讨论思路
- 当一个组织没有任何历史可靠性数据作为依据时,应当如何设定它的第一批 SLO?
- 当错误预算已经耗尽、而一次重大发布又已经箭在弦上时,谁有权推翻这次冻结,这个决策又该如何被记录下来?
- 中心化、嵌入式还是混合式的 SRE 模式适合你的组织,什么情况会促使你做出改变?
- 你会如何权衡多一个”9”的可用性,与同样的投入本可以资助的那些功能之间的价值?
- 在你的场景下,什么才算是琐事,“有价值的人工判断”与”可以消除的重复劳动”之间的界线在哪里?
- 面向公民的政府服务与内部企业工具之间,可靠性目标应当有怎样的不同?
关键要点
- SRE 把软件工程应用到运维之中,把可靠性当作一项可度量、可资助的功能来对待。
- SLI、SLO 和 SLA 把可靠性从个人观点变成了共同认可的数字;要让 SLO 比 SLA 更严格。
- 错误预算通过把”可靠性与速度”的取舍变得明确且提前商定好,来统一开发者和运维人员的激励方向。
- 要度量并限制琐事,并把自动化当作一等公民级别的工程活动,从而让运维能够以亚线性的方式扩展。
- 依据需求预测来规划容量,并尊重资源调配的提前期,尤其是在面对季节性峰值的时候。
- 有意识地选择一种 SRE 组织模式,并明确定义清晰的合作模型和生产就绪门槛。
参考资料与延伸阅读
- Betsy Beyer、Chris Jones、Jennifer Petoff、Niall Richard Murphy,Site Reliability Engineering: How Google Runs Production Systems
- Betsy Beyer、Niall Richard Murphy、David K. Rensin、Kent Kawahara、Stephen Thorne,The Site Reliability Workbook: Practical Ways to Implement SRE
- David N. Blank-Edelman(编),Seeking SRE: Conversations About Running Production Systems at Scale
- Thomas A. Limoncelli、Strata R. Chalup、Christina J. Hogan,The Practice of Cloud System Administration
- Nicole Forsgren、Jez Humble、Gene Kim,Accelerate: The Science of Lean Software and DevOps