企业如何规模化地赋能团队,以应对上云后所遭遇的未知暗债?在解决这个复杂问题的过程中,混沌工程诞生了。
企业上云后遭遇未知暗债
什么是暗债?讨论系统复杂性的STELLA 报告指出,“暗债存在于复杂系统中,它所产生的异常,会导致复杂系统出现故障。 暗债产生时,无法识别。 它不会使得系统停顿,而是会产生异常。 当硬件或软件与框架其他部分发生不可预见的交互时,暗债就会产生。 由于暗债不可见,只能通过系统发生异常才能感知它的存在,所以暗债无法避免。”
企业的应用软件系统,无论是从原先的单体架构整体平移到云环境,还是进行了微服务化改造后逐步上云,软件系统运行所依赖的环境以及软件系统自身,都会变得越来越复杂。当软件系统内部的服务之间,以及与其所依赖的云平台发生交互时,就会产生不可避免的暗债,导致系统出现不可预知的故障。
混沌工程要解决的问题
Netflix公司在2008年,将其单体架构的系统从数据中心迁移到AWS云平台时,就出现了暗债所导致的未知故障。比如系统运行所依赖的AWS实例会突然消失,且不会发出警告。
由于Netflix的业务完全依赖AWS的云服务,所以上述暗债是会影响公司所有业务。如何才能规模化地应对这种全局性的暗债呢?
Netflix工程师尝试了各种方法来应对这种暗债,最后发现“混沌猴”效果不错,于是就将其保留了下来。
混沌猴是一个应用程序,它会模拟触发上述暗债,即遍历AWS实例集群,然后从每个集群中随机选择一个实例,在上班时间关闭,且不发出警告。由于这是在生产环境注入了故障,所以工程师们会将应对这种暗债,作为最高优先级的工作来完成,从而将规模化应对这种暗债最终落地。
Netflix公司从中逐渐发展出了混沌工程这门学科。
从中能够看出,混沌工程就是通过在复杂的分布式系统上进行故障注入实验,以便在企业内规模化地促进开发团队进行系统稳定性的赋能,从而应对不可预知的复杂系统中的暗债。
混沌工程赋能的核心
混沌工程赋能的核心,就是规模化地赋能开发团队各角色(业务、开发、测试、运维),更全面地理解复杂系统如何运行及如何失效,加强系统稳定性设计,以便快速应对未知暗债。
赋能开发团队,需要成立赋能团队。赋能团队的主要赋能工作,包括两个方面:首先为开发团队提供咨询服务,之后在此基础上,为开发团队提供适用的工具或平台。
为混沌工程赋能创造好的条件
要为混沌工程赋能创造好的条件,可以做下面12件事(参考了Reliability Calculator:https://www.gremlin.com/reliability-calculator/)。
- 为了将有限的资源投入到最关键的软件系统服务上,需要对服务按照业务关键性,建立分级机制。第1级服务面向用户,能够持续产生收入,或者其他第1级服务需要强依赖于该服务。第2级服务既可面向用户,也可不必,但其他服务必然需要强依赖于该服务,或者该服务需要准确和持续地持久化数据。第3级服务既不面向用户,其他服务也无须强依赖于该服务,如果该服务失效,也不会产生什么数据损坏。人们对第1级和第2级服务的系统稳定性的期望,要高于第3级。
- 划分软件系统服务质量与稳定性“责任田”。为每个第1级和第2级服务,分配长期稳定的开发团队,专门负责该服务的软件质量和系统稳定性,而不是按项目制那样动态从资源池中抽取人力做临时的项目,造成服务的软件质量和系统稳定性无人长期负责的问题。
- 运用质量内建、系统稳定性设计、架构演进与守护,提升软件系统服务自身质量,以避免在分布式生产环境运行时,服务自身缺陷与生产环境暗债交织在一起,增大应对暗债的难度和复杂度。
- 建立“任何高可用设计都是待在 生产环境验证的假设”的意识,促使开发团队各角色在生产环境进行系统稳定性实验。
- 由于软件架构是各种非功能性需求权衡后的结果,所以描绘结果的架构图,需要与记录权衡过程的架构决策记录结合起来,才能了解结果背后的前因后果,为理解和分析复杂系统的行为提供细致的上下文。因此,需要运用持续更新的软件架构图和架构决策记录,来对齐开发团队各角色对复杂系统的架构认知。
- 建立软件系统服务专用的工具平台,并具备主动监控或告警阀值机制,以便记录混沌工程实验的过程,理解和分析复杂系统的运行和失效模式,并快速应对故障。
- 衡量系统稳定性,需要度量有关故障的两个指标:度量故障频率的服务平均故障间隔时⻓ (Mean time between failure, MTBF),和度量故障修复速度的服务平均恢复时⻓ (Mean time to recover, MTTR)。服务平均故障间隔时⻓,指给定服务在两次事故之间的平均时长。比如,去年发生了5起事故,那么服务平均故障间隔时⻓就接近于1752小时。故障平均恢复时长,指服务从故障发生开始(注意不是从故障被检测到开始),到服务恢复的平均时长。这里的恢复,既包括自动化恢复,也包括手工恢复。
- 当事故发生时,应该能够立即找到灾难恢复预案,通过执行其中的步骤,来检测并减轻灾难影响。
- 建立服务稳定性表现的内部期望,需要建立服务等级目标SLO(可以与对外发布的服务等级协议SLA不同)。SLO一般用一个百分数来度量,比如99.9%(3个9)。
- 为了判断是否需要加强系统稳定性的建设,需要建立故障预算。故障预算指服务的 SLO 与实际测量的正常运行时长之间的差异。例如,服务 A 当月的系统可用性 SLO 为 99.999%。 这意味着服务的故障预算,是当月可以有 0.001% 的停机时间(即25.92 秒)。如果事件导致停机时间超过 5 秒,则“花费”了 19% 的错误预算。只要有剩余预算,正常的工程工作就可以继续。但如果停机时间超出了预算,那么工程工作就应该转向额外的测试、混沌工程和开发工作,以使系统更具韧性。
- 为了能够快速应对故障,需要对建立生产环境轮流值班机制。对于第1级服务,需要建立7x24的轮流值班机制。对于第2级服务,需要建立工作时间轮流值班机制。
- 开始进行混沌工程实验:混沌工程是一种进行深思熟虑并有计划的实验,以了解复杂系统在出现故障时的运行方式。实验一般有三个步骤:1)识别系统在出现问题时的稳态假设;2)设计并对系统实施控制了爆炸半径的实验;3)衡量系统失效过程中每一步对业务的影响,寻找系统运行成功或失效的迹象。实验结束后,开发团队就可以更好地了解系统的实际行为。
混沌工程的成效度量
混沌工程是一个赋能活动,其成效度量可以参考在培训界常用的Kirkpatrick模型。该模型是美国威斯康星大学教授Kirkpatrick,于1954年提出“4级培训成效评估模型”。
4级培训成效评估模型
混沌工程赋能的过程
要想实现混沌工程规模化赋能,需要运用“跨越鸿沟”的规模化思路,通过解决早期大众的痛点,来跨越从早期采纳者到早期大众的鸿沟,从而逐渐实现规模化。混沌工程赋能的过程,可以包含以下9步。
- 赋能团队
成立赋能团队,为开发团队的混沌工程实践,提供咨询服务和工具。
- 选择服务
选择为生产环境稳定性所困扰的团队,及其所开发和维护的软件系统服务,作为试点。因为这样的团队,才有动力提升系统稳定性。
- 搞实战营
持续搞混沌工程实战营,每一期3个月,聚焦一个试点服务,重点培养混沌工程赋能种子,优化过程和工具,沉淀案例并分享。下一期换一个服务,再搞实战营,上一期的种子可以作为下一期的讲师,持续搞实战营,以便逐步增加赋能种子,并优化工具,逐步通过种子和工具进行混沌工程的规模化。
- 挑选种子
选择具有编程能力,且具备混沌工程理念的开发人员,作为赋能种子。每期实战营可选2位种子。
- 现状调研
调研与访谈试点团队的系统稳定性现状和痛点,可以使用问卷,加快调研速度。
- 导入理念
通过培训的形式,为试点团队业务、开发、测试、运维各个关键角色,导入混沌工程理念。在导入理念时,内容一定要紧扣团队痛点。
- 沉淀案例
沉淀试点团队通过混沌工程实践,有效应对系统稳定性痛点的案例。以下7步是常见的混沌工程实验步骤。
1)稳态假说
召集试点团队业务、开发、测试、运维各个关键角色,参考软件架构图和系统稳定性痛点,共创稳态假说。
2)现实事件
试点团队参照现实世界的真实事件,设计故障注入方案和混沌实验。
3)观测影响
试点团队准备好观测工具,以便搜集实验数据,并在故障影响业务时及时中止实验。
4)稳定设计
试点团队针对共创出的稳态假说和现实事件,进行系统稳定性设计。
5)应急预案
试点团队针对故障注入实验,设计应急预案和随时中止实验的大红按钮,确保实验不会影响业务。
6)进行实验
试点团队业务、开发、测试和运维等关键角色需要全程参与实验,并扮演总指挥、操作员、观察员、记录员、安全员等角色,按照演练手册,各司其职。
7)学习改进
实验结束后,试点团队需要回顾实验整个过程,识别改进项(包括工具方面的改进项),并分析实验观测数据,编写实验报告,落地各个改进项。
- 案例分享
试点团队按照Kirkpatrick模型,识别混沌工程实验应对系统稳定性痛点的成效,连同实验的整个过程,一起分享给其他团队,以便为规模化营造氛围。
- 优化过程
试点团队通过混沌工程实战营,总结适合自身特点的混沌工程实践过程,并持续优化,以便持续提升系统稳定性,并为给其他团队进行规模化推广,提供参考。
总结
混沌工程实践,本质上是赋能团队,通过提供咨询服务和工具,为复杂系统的开发团队进行规模化的系统稳定性赋能活动。要想让规模化赋能顺利开展,需要运用“跨越鸿沟”的规模化思路,通过解决早期大众的最大痛点,来跨越从早期采纳者到早期大众的鸿沟,从而逐渐实现规模化。而吸引早期大众的关键特性,就是能赋能早期大众更全面地理解复杂系统的运行和失效方式,从而设计更具韧性的系统,并能更加快速地应对暗债,以验证高可用的设计。