8.6

View in English

8.6 发布管理与渐进式交付

概述与动机

现代发布管理中最有用的理念同时也是最简单的:交付代码与暴露一项功能是两个不同的事件,你应该能够只做其中一件而不做另一件。第 8.1 章(CI/CD 与交付)负责把你的变更构建一次、测试一次,并以不可变制品的形式提升上去。本章讲的是接下来发生的事:你如何把已部署的代码,逐步地、安全地、并保留一条快速回退路径地,转变为真实用户的实际体验。部署(Deployment)指的是把代码安装到服务器上。发布(Release)指的是让用户能够接触到某项能力。当你把两者分开后,部署会变得常规而乏味,而发布则会成为一项受控的、可逆的决定。

对于大型团队而言,这种分离改变了发布这件事的情绪温度。当数十个服务和数百名工程师每天都在改动生产环境时,一种”部署即发布”的耦合模型意味着每一次面向用户的变更都是一次高风险、一次性完成的事件。解耦让你可以把未完成的工作合并到一个开关背后,把一项功能推给百分之一的流量,观察数据,然后在不触碰构建产物的情况下扩大或撤回。渐进式交付(Progressive delivery)正是这一整套做法的统称:在自动化检查决定是否继续的同时,把一项变更逐步释放给不断扩大的受众。

企业与政府场景还增加了协调与举证的需求。一个支付平台要跨多个必须就模式(schema)达成一致的服务进行发布。一个公共机构在运营授权(authority to operate)和正式变更控制之下运作,审计人员想要确切知道究竟是谁在什么时候接触到了什么。做得好的话,渐进式交付能同时满足快速行动的愿望与证明可控的义务,因为限制爆炸半径的同一套机制,恰恰也会产生一份可审计的发布记录。

关键原则

  • 部署不等于发布。 先悄悄交付代码,再有意识地打开它。
  • 先小爆炸半径。 在暴露给所有人之前,先暴露给少数人。
  • 每一次发布都要有倒挡。 如果你无法在几秒钟内回滚,说明这次发布的设计还没有完成。
  • 让信号驱动推进。 由健康指标和错误预算来决定发布是否推进,而不是日历或乐观情绪。
  • 开关在被移除之前都是一项负债。 每一个开关都是你必须维护、并最终删除的代码。
  • 让数据库变更在两个方向上都能存活。 上线与回滚都必须对同一个模式(schema)保持安全。
  • 审批应当记录,而不是阻碍。 审计证据应当是流水线的副产品,而不是一场每周例会。

建议

用功能开关把部署与发布分开

功能开关(feature toggle),或称功能标志(feature flag),是一个在运行时决定某段代码路径是否生效的开关,无需重新部署。把开关当作一套有类型的词汇表来对待,因为它们的生命周期各不相同。发布开关(release flag)用来隐藏尚未完成的工作,生命周期为几天到几周。运维开关(operational flag)(也就是紧急开关,kill switch)让你在负载过高时关闭某个子系统,生命周期可能无限期存在。实验开关(experiment flag)用于为受控测试拆分流量,生命周期等同于实验的长度。权限开关(permission flag)根据套餐或角色控制某项能力,实际上是永久性的。为每一个开关指定一位负责人、一个类型、一个默认值,以及一个预期的移除日期。默认值应当是安全的那一个,这样当开关服务出现故障时,会关闭回退到已知良好的行为,而不是开放给未经测试的路径。

按服务层级选择渐进式交付模式

正如第 8.1 章在讨论部署策略时所主张的,把上线机制与爆炸半径相匹配。金丝雀发布(canary release)把一小部分流量引向新版本,只有在健康状况良好时才会扩大范围。蓝绿部署(blue-green deployment)保留两套生产环境,并在两者之间切换流量,从而实现即时切换和即时回退。滚动部署(rolling deployment)分批替换实例。分环部署(ring-based deployment)通过一系列命名的受众逐步扩展:先是内部用户,然后是测试用户群,然后是一个小地区,最后是所有人。对大型组织来说,分环是最有用的框架,因为它在每一步都明确说明了谁被暴露在外,而这正是审计人员和事件响应人员都想知道的信息。容器平台与编排(第 8.3 章)提供了让这些模式能够廉价运行的流量调度原语。

用健康检查和自动回滚来把关上线

在发布之前而不是在事故发生期间,定义客观的健康标准。自动化分析会在错误率、延迟和饱和度方面比较金丝雀版本与基线版本,并在无需人工察觉的情况下直接推进或回退。把推进决策与来自站点可靠性工程(第 9.1 章)的服务水平目标(service-level objective)和错误预算绑定:当预算健康时自由发布,当预算耗尽时流水线拒绝推进,直到服务稳定下来。自动回滚之所以最为重要,是因为它消除了那种会把一个小回归变成一场重大故障的犹豫。快速回退同时也是你成本最低的事故控制手段:一次只需几秒钟的回滚,能在你的事故处理流程(第 9.3 章)完全启动之前就缩小爆炸半径。你借此改善的变更失败率和恢复时间,正是你的交付流水线所跟踪的同一批流动性与稳定性信号(第 11.2 章)。

用暗启动和影子流量来降低风险

有些变更后果太过严重,不适合第一次就以完全暴露的方式接触真实用户。暗启动(Dark launching)以关闭状态交付一项功能,然后先在内部或针对一小部分生产流量运行它,再让任何人看到它。影子流量(Shadow traffic)把线上真实请求复制一份发送到新的代码路径,并丢弃其响应,这样你就能在对用户零影响的前提下衡量真实负载和正确性。这些技术让你能够在真实流量下验证一次重写或一个新依赖,而这是任何预发布环境都无法忠实复现的。把它们与你为金丝雀发布使用的同一套健康分析配对使用。

通过同一套开关系统运行受控实验

实验开关正是发布工程与产品学习交汇的地方。一次 A/B 测试(A/B testing)把不同变体分发给可比较的用户群体,并衡量一个选定的结果指标,为第 7.4 章讨论的产品分析实践提供数据。对安全性发布和实验都复用同一套开关和定向系统,这样你就只有一条审计轨迹和一个紧急开关,而不是两套互相对不上、在”谁属于哪个分桶”这个问题上意见不一的并行开关体系。

通过扩展与收缩让数据库保持向后兼容

只有当模式(schema)能够同时容忍新旧两版代码时,上线与回滚才能保持安全,而这在任何渐进式上线过程中都是不可避免的。使用扩展与收缩(expand and contract,也称并行变更 parallel change)模式:首先通过一次向后兼容的迁移来扩展,添加新的列或表;然后部署会同时写入新旧两种结构的代码;然后回填数据;然后把读取切换过去;直到很久之后,等确认没有正在运行的代码还依赖旧结构时,才收缩,移除旧结构。永远不要把破坏性的迁移和需要它的那次部署捆绑在一起。正是这种纪律,才让你能够在数据库尚未”超前”的情况下把代码回滚,它也直接关联到你的测试策略(第 2.4 章),后者必须覆盖新旧版本混合共存的窗口期。

让变更管理记录,而不是阻碍

通过预先批准某些类别的变更,来调和审计与流动性之间的关系。定义标准的、低风险的变更类型,让它们自动流经流水线,并记录下谁批准了它、跑了哪些测试、部署了哪个制品,以及在每一环暴露给了哪些受众。把人工的变更咨询评审留给真正高风险的变更。一个审查每一次常规部署的传统变更控制(change control)委员会,会变成一个瓶颈,反而把团队推向更大、更冒险的批次,这与它本意恰恰相反。在政府场景中,当上线工具能够产出控制框架所需的证据时,运营授权(authority to operate)与正式变更控制完全可以与渐进式交付共存,此时基于分环的记录本身就是审计制品。

权衡取舍:利与弊

模式优点缺点最适合场景
金丝雀发布数据驱动,爆炸半径小需要良好的指标和足够的流量面向大量用户的服务
蓝绿部署即时切换与回滚切换期间环境成本翻倍需要快速回退的关键服务
滚动部署成本低、简单,无需额外环境回滚慢,新旧版本同时在线无状态的内部服务
分环部署受众命名清晰,审计轨迹清楚全量上线较慢;需要更多协调受监管及多服务体系
功能开关把部署与发布解耦;可即时熔断开关债务;测试组合数增长需要安全交付未完成工作的团队
发布列车节奏可预测,协调容易耦合了许多变更;需要等车多团队共享一次发布
按需发布批次小,反馈快跨团队协调更难高信任度的持续交付团队

核心张力存在于协调与独立性之间。发布列车(Release trains)把许多团队的变更打包进一个固定的时间表,这易于推理,但会强迫一个已完成的变更去等待,并把互不相关的工作耦合进同一个事件。按需发布(On-demand release)让每个团队在准备好时就交付,这更快,但要求服务能够独立部署并保持向后兼容。通常的解决办法是在制品和模式(schema)层面上解耦,让团队能够按需发布,然后用开关和分环来协调一个跨服务功能真正打开的那个用户可见的时刻。这样一来,技术层面的发布与产品层面的上线就成了两个独立的决定,彼此互不阻塞。

与团队讨论的问题

  1. 当一次发布在凌晨两点出了问题时,回退需要多少秒,是谁或什么东西按下了那个开关? 诚实的答案会揭示出你是否真正把部署和发布分开了,还是只是在一个耦合的流程上加了几个开关。一次需要重新构建、需要撤销数据库迁移、或者需要呼叫一个人来做决定的”回滚”,根本不是回滚,而是第二场事故。拿出你排名前三的服务的实际机制:那个能反转暴露状态的开关或流量切换、能自动触发它的健康信号,以及让反转变得安全的模式(schema)保证。对于一个大型体系来说,这决定了你真实的爆炸半径,因为快速的自动反转正是阻止一次回归演变成一场故障的关键。如果答案是以会议次数而不是秒数来衡量的,那就是首先要修复的东西。

  2. 你们退役开关的策略是什么,你们目前背负着多少开关债务? 每一个功能开关都是你代码中的一个分叉,它会成倍增加你必须推理和测试的状态数量,而一个已经超出使用期限的开关纯粹是一项负债。现在就定下规则:每个发布开关都要有负责人和到期日,过期的开关要出现在一个仪表盘上,移除它们是计划中的工作,而不是”以后再清理”。拿出当前存活开关的数量、它们的存续时间,以及有多少已经超过了预定的移除日期。在一个大型代码库中,失控的开关会变成没人敢删除的永久性条件复杂度,而这套安全机制本身会变成缺陷的来源。团队对这个数字的容忍度,其实就是它对待运维卫生这件事有多认真的一种声明。

  3. 你们的变更审批流程究竟是让发布更安全,还是只是更慢? 许多组织运行着一个审查每一次部署的变更咨询委员会,而一个令人不安的问题是,它究竟有没有真正阻止过一次糟糕的变更,还是只是增加了延迟。拿出数据:审批的中位延迟、经过委员会评审的变更与预先批准的变更之间的变更失败率对比,以及评审有多频繁地把小变更打包成了更大、更危险的变更。目标是把人工评审留给真正高风险的变更,同时让标准变更带着自动记录的证据流经流水线。对于受监管和政府场景,要核实上线工具能够产出控制框架所需的审计记录,这样控制就成了交付的副产品,而不是挡在它前面的一道闸门。如果评审只增加延迟而不能降低失败率,那它就是披着合规外衣的表演。

  4. 你们愿意让机器根据哪些客观健康信号采取行动,每一个顶级服务是否真的具备足够好的指标来作为把关依据? 自动化的金丝雀分析和错误预算把关,只有在错误率、延迟和饱和度的测量足够干净、可以让人信任一次推进或回滚决定而无需人工介入时才有效,而许多团队都是在一次事故中才发现自己的信号太嘈杂或太稀疏,根本无法据此做决定。对于一个大型体系来说,这决定了你的发布量中有多大比例能够安全地自动流动,而不需要人工时刻盯着,这正是一个能够扩展的平台和一个需要有人盯着每一次上线的平台之间的区别。拿出你三个最关键服务的实际仪表盘:你用来把关的指标、让一次金丝雀发布具有统计意义所需的流量规模,以及你的自动化分析的假阳性率。在受监管和政府场景中,这些相同的信号会汇入可审计的记录,因此糟糕的可观测性既是一个可靠性缺口,也是一个合规缺口,为指标质量投入资金应当是计划中一个明确列出的条目,而不是一个想当然的能力。

  5. 你们的模式(schema)变更是否真的能经受住回滚的考验,在交付之前你们如何证明新旧版本混合共存的窗口期是安全的? 渐进式交付承诺了一条快速的倒挡,但一次与某项功能耦合在一起的破坏性迁移,会悄悄使这一承诺失效,因为把代码回滚之后,它面对的却是一个已经”超前”的数据库。对于一个多服务共享同一个模式的大型组织来说,这种风险会累积放大:一个团队的收缩步骤可能会困住另一个团队的回滚,因此”扩展与收缩”这套纪律必须成为一个共享的标准,而不是某个团队的局部习惯。拿出你的迁移操作手册以及它被遵循的证据:你如何把扩展与收缩分开、双写和回填是否在负载下经过测试,以及你的测试套件如何让旧代码在新模式下运行、让新代码在旧模式下运行。对于承载着长期存在的数据和正式变更控制的企业与政府体系来说,一次不可逆的迁移不仅仅是故障风险,更是一次数据完整性与审计层面的暴露,一个预定的维护窗口无法挽救这一点。

  6. 当一个跨服务的功能横跨了交付速度不同的多个团队时,谁拥有它被打开那一刻的决定权,你们如何在不耦合各团队部署的前提下进行协调? 把部署和发布分开的整个意义在于,每个团队都可以独立地交付自己的制品,同时由一个开关来控制用户可见的上线时刻,但这只有在有人真正拥有跨服务边界的上线决定权和开关定向权的情况下才成立。对大型团队来说,其失败模式是一列没人选择过的事实上的发布列车:一个慢的服务拖着所有其他团队等待,或者一次未经协调的开关切换暴露出一个只连接了一半的功能。拿出你下一次多服务上线的依赖关系图、上线开关的负责人,以及让每个服务能够按自己的节奏部署的向后兼容性保证。在有着正式上线审批的企业与政府项目中,明确谁来为跨服务的开启签字,以及他们会看到什么证据,这样协调好的上线就是一个刻意的、有记录的决定,而不是恰好谁最后合并代码所导致的意外。

行业视角

初创企业。 即使只有三名工程师,把部署与发布分开也是值得做的事,但要让它保持低成本。把新工作包在一个默认关闭的发布开关里,直接交付到主干,在面向客户之前先为自己打开功能,这样一个未完成的变更就永远不会阻塞一次部署。跳过你没有人手维护的重型金丝雀分析平台:一个托管的开关服务和一个可靠的紧急开关就能买到大部分的安全性,而由一个人负责每周清理开关的仪式,就能防止债务吞噬你的速度。

小型企业。 没有专门的发布工程师、预算又紧张的情况下,依靠你现有平台已经提供的渐进式交付能力,而不是自建一套上线系统。托管主机、一个功能开关的 SaaS 服务,或者你所用框架内置的分阶段上线功能,通常就足以覆盖你所需要的小爆炸半径。把倒挡这件事当作必须做对的重点:一个能在几秒钟内关闭的变更,远比你没有时间去调优的复杂自动化分析更重要。

企业。 问题在于跨众多团队和服务的一致性:一套有负责人、有类型、有到期日的共享开关词汇表,标准化的分环上线,以及在各处以相同方式应用的错误预算把关,让各团队不再各自发明一套相互竞争的开关体系。把开关债务当作一个覆盖全体系的指标来治理,把扩展与收缩迁移标准化,确保一个团队的模式变更永远不会困住另一个团队的回滚,并让可审计的上线记录成为每个服务以相同格式产出的副产品。预先批准标准变更,把人工评审留给真正高风险的变更,让控制能够扩展,而不需要一个委员会卡在关键路径上。

政府。 采购规则、透明度和公共问责塑造着每一次发布。让上线工具成为审计证据的来源,使每一次分环扩展都能记录下批准的权限方、跑过的测试、制品哈希,以及被暴露的确切人群,让运营授权(authority to operate)能够与渐进式交付共存,而不是相互对抗。优先选择蓝绿或分环模式,因为它们命名的受众范围,审计人员和事件响应人员都能读懂;在任何公民受到影响之前,用影子流量针对真实案例验证有重大影响的变更;并把可审计的记录作为控制框架所接受的制品,取代一个预定的、大爆炸式的窗口期。

案例

初创企业。 一家十人的 SaaS 公司每天多次直接交付到主干,并把每一项新能力都包在一个默认关闭的发布开关里。一次有风险的新计费集成以暗启动的方式上线:他们针对它运行了一周的影子流量,观察它如何处理真实请求形态而对客户零影响,然后逐环上线,先从自己的账户和少数友好的测试客户开始。当错误率在百分之五的分环上飙升时,一次自动检查在几秒钟内关闭了开关,他们在周一从容地进行了排查。一名工程师负责每周的开关清理仪式,这样开关就永远不会堆积。

企业。 一家全球性支付公司协调一次横跨六个服务和一个共享模式的变更。每个团队都使用扩展与收缩独立地、向后兼容地部署自己的制品,因此新增的列早在任何用户看到该功能之前,就已经存在并被双写。用户可见的上线是通过一个实验开关来实现的,按照与错误预算健康状况挂钩的分环推进:先内部,再一个小国家,再逐步扩大的百分比,每一步都由自动化的金丝雀分析来决定推进还是回退。一个开关治理服务在整个体系范围内强制执行负责人、类型和到期日,预先批准的标准变更无需委员会即可流转,只有模式收缩这一步才需要人工评审。每一次分环切换都会被记录下来,审计轨迹因此自然而然地写好了。

政府。 一家全国性的福利机构在运营授权(authority to operate)和正式变更控制之下运作。它没有把渐进式交付当作一项合规风险,而是让上线工具成为审计证据的来源:每一次分环扩展都会记录下批准的权限方、跑过的测试、制品哈希,以及被暴露的确切人群。一项新的资格计算功能以暗启动方式上线,并用影子流量针对真实案例进行验证,然后按地区逐步上线,配合蓝绿切换以实现即时回退。标准变更被预先分类,因此常规工作不必排在委员会后面等待,而高风险的政策变更仍然要经过正式评审。可审计的上线记录,比旧有的季度性大爆炸式发布更完整地满足了控制框架的要求。

商业案例:动机、投资回报率与总拥有成本

渐进式交付的回报,主要体现在被避免的事故及其被缩小的严重程度上。一个只触达百分之一用户、并会自动回退的变更所付出的代价可以忽略不计,而同一个缺陷在全量暴露下可能意味着数小时的故障、紧急响应和声誉损失。把部署与发布解耦,还把发布本身从一个有计划的、高压力的事件,变成了一件常规的事,这降低了随团队规模非线性增长的协调税。把上线决定和部署决定分开,让产品和工程能够按各自的节奏推进,这样一个市场营销的日期就永远不会强迫代码进行一次高风险的冻结。

相对于这些收益,总拥有成本是真实存在的,但并不高昂。你需要投资于一个开关平台、金丝雀分析工具、足够好可以用来把关的健康指标,以及保持模式向后兼容的纪律。经常性的成本是开关卫生,以及开关所带来的更大的测试组合,这正是失控的开关体系成为这项实践变得昂贵的主要方式。不采纳它的代价体现在爆炸半径上:每一次发布都是全有或全无,回滚缓慢,一次糟糕的部署就可能让所有人同时宕机。对于受监管的组织而言,合规方面的红利是决定性的,因为限制暴露范围的同一套机制,也会产生原本需要手工整理的可审计证据。

反模式与陷阱

  • 部署等于发布。 把两者耦合在一起,会让每一次面向用户的变更都成为一次高风险、一次性完成的事件,且没有倒挡。
  • 开关债务。 超出使用期限的开关会变成没人敢删除的永久性条件复杂度。
  • 默认开放失效的开关。 一次在开关服务故障时默认切换到未经测试的新路径的行为,会把一个小波动变成一场故障。
  • 需要撤销模式变更的回滚。 与某项功能一起交付的破坏性迁移,会让你无法安全地回滚代码。
  • 凭感觉进行人工推进。 因为一次上线”看起来还行”就推进它,而不是依据明确定义的健康标准和错误预算。
  • 只设计如何打开、不设计如何关闭的上线。 设计了如何打开一项功能,却没有设计如何关闭它。
  • 变更委员会的橡皮图章。 一场从不拒绝任何事的评审只会增加延迟而不会增加安全性,并把团队推向更大的批次。
  • 实验开关和安全开关分处两个系统。 两套互相对不上、在”谁属于哪个分桶”上意见不一的开关体系,让审计面翻倍。

成熟度模型

  • 第一级,启动(Initiate): 部署和发布是同一个事件。变更一次性全部发出,回滚意味着手动重新部署一个旧构建,模式迁移是破坏性的且与功能耦合在一起。任何渐进式的暴露都是临时的、被动的、且未被记录的。
  • 第二级,发展(Develop): 部分团队使用功能开关来隐藏未完成的工作,但它们缺少负责人、类型和到期日,债务正在累积。金丝雀或蓝绿部署被用于少数关键服务,但各团队应用得并不一致。回滚已经脚本化,但仍需人工触发,模式变更也只是偶尔才向后兼容。
  • 第三级,标准化(Standardize): 部署和发布在整个组织中默认是分开的。开关有类型、有负责人、会到期,具有安全的默认值,遵循一套文档化并被强制执行的标准。带有分环上线和自动化金丝雀分析的渐进式交付是常态,扩展与收缩迁移是强制要求,标准变更带着自动记录的证据流经流水线。
  • 第四级,管理(Manage): 发布流程被度量,并依据数据加以控制。变更失败率、平均恢复时间、回滚延迟、开关数量和年龄,以及金丝雀分析的假阳性率,都会被跟踪并与基线和错误预算比较,上线过程会依据这些服务水平目标(第 9.1 章)进行把关,让推进和回滚能够根据明确定义的健康信号自动执行。开关债务作为一个覆盖全体系的指标被上报,并按计划退役,与上线标准的偏差会出现在仪表盘上,而不是出现在事后总结里。
  • 第五级,协同(Orchestrate): 渐进式交付被持续改进,并整合到整个组织之中。暗启动和影子流量被常态化地用来为重大变更降低风险,实验和安全性上线共享同一套开关系统和审计轨迹,发布策略会根据错误预算状况实时调整。可审计的上线记录作为副产品满足了变更控制(第 9.3 章)的要求,而组织会依据实证数据,随着体系和风险状况的变化,不断调优自己的分环、把关条件和阈值。

讨论思路

  1. 对你最关键的服务而言,自动的、由健康状况把关的回滚与人工决策之间,正确的分界线应该划在哪里,你愿意信任哪种信号到让机器独立行动的程度?
  2. 实验开关和发布开关应该共享一个平台和一个紧急开关吗,还是把它们合并在一起反而会制造出比它消除的更多风险?
  3. 当一项功能横跨几个交付速度不同的团队时,你如何在发布列车和按需发布之间做出选择?
  4. 在你的代码库中,一个发布开关诚实的半衰期是多久,怎样才能让移除开关和创建开关一样成为一件常规的事?
  5. 错误预算状况应该如何改变谁被允许发布,以及在预算耗尽时,谁拥有冻结发布的决定权?
  6. 在你所处的受监管场景中,为了让控制框架接受渐进式交付而不是一个预定的发布窗口,一次上线必须产出哪些具体证据?

关键要点

  • 把部署与发布分开。 交付代码和暴露一项功能是两个不同的决定,而开关正是把它们解耦的手段。
  • 渐进式地上线。 金丝雀、蓝绿、滚动和分环模式都能限制爆炸半径;根据风险为每个服务层级各自选择。
  • 依据健康状况和错误预算把关。 让明确定义的信号和服务水平目标(第 9.1 章)驱动自动推进和回滚,而不是日历或乐观情绪。
  • 先设计倒挡。 快速、安全的回滚能在你的事故处理流程(第 9.3 章)完全启动之前就缩小爆炸半径。
  • 为每一个开关定类型、定负责人、定到期日。 发布开关、运维开关、实验开关和权限开关各有不同的生命周期;失控的开关会变成债务。
  • 让模式变更向后兼容。 使用扩展与收缩,让上线和回滚在新旧版本混合共存的窗口期内(第 2.4 章)都能保持安全。
  • 让审批负责记录,而不是阻碍。 预先批准标准变更,把人工评审留给高风险变更,这样上线记录本身就是审计证据。

参考文献与延伸阅读

  • Jez Humble and David Farley, Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation.
  • Nicole Forsgren, Jez Humble, and Gene Kim, Accelerate: The Science of Lean Software and DevOps.
  • Gene Kim, Jez Humble, Patrick Debois, and John Willis, The DevOps Handbook.
  • Betsy Beyer, Chris Jones, Jennifer Petoff, and Niall Richard Murphy (eds.), Site Reliability Engineering.
  • Pete Hodgson, “Feature Toggles (Feature Flags)” (essay on martinfowler.com).
  • Danilo Sato, “Canary Release” and Martin Fowler, “BlueGreenDeployment” (essays on martinfowler.com).
  • Sam Newman, Building Microservices: Designing Fine-Grained Systems (expand-and-contract and independent deployability).
  • Pramod Sadalage and Scott Ambler, Refactoring Databases: Evolutionary Database Design (parallel-change schema migrations).
  • Ron Kohavi, Diane Tang, and Ya Xu, Trustworthy Online Controlled Experiments: A Practical Guide to A/B Testing.
  • James Governor, “Progressive Delivery” (RedMonk, the coining of the term).