这是鼎叔的第五十五篇原创文章。行业大牛和刚毕业的小白,都可以进来聊聊。
欢迎关注本专栏和微信公众号《敏捷测试转型》,大量原创思考文章陆续推出。
知名公司的混沌工程实践有:谷歌的 DiRT 计划(灾难恢复测试,已经进行了数千次),Slack 的灾难剧场,微软云平台混沌工程等。很多公司把混沌工程实验做成 “Game Day”,用游戏比赛的有趣竞争状态来进行混沌实验,而不是制造如临大敌的气氛。
混沌工程的系统方法、原则和步骤,不止应用于分布式大型软件,也应用于软硬件一体的互联系统,如汽车自动驾驶系统。混沌工程也应用到了网络安全领域。
本文详细介绍各大企业实践混沌工程的优秀流程,经验教训,人为阻力,人和组织的能力提升,我们能从中学习到一些宝贵的洞见。
演练前须知
一 设计模式的容错性
始终让备用容量在线,然后考虑如何让出故障的计算机从服务中移除,进一步实现自动替换故障机器。整个替换的耗时短暂且合理,重试次数合理。
二 保持数据持久性
所有演练规划和涉及的故障都必须确保数据不会丢失。因此可能需要保留额外的数据副本。
三 高效协作和开放心态
当这些人讨论灾难实验计划时,一些被孤立的知识就能浮现出来,对某个人而言显而易见的漏洞,对其他人则是不确定的风险。这个讨论环节立马就获得收益,相关的假说和实验就没有必要安排了,先解决该漏洞再说。
混沌工程在高效协作下最有价值。但混沌工程团队对其他人的系统进行实验,双方很可能会形成冲突关系,导致混沌工程遭到拒绝。
如果混沌工程师的心态是帮助其他团队,并通过工具提供支持,那冲突就能大大降低。混沌工程参与者就拥有对系统可靠性的共同所有权。
如果发现系统漏洞的证据都被锁定在专有系统或专有协议中,其真实价值就会被损害,所以应该遵循开放的原则来实践混沌工程,鼓励开放培训资源、获取权限、同行评审、方法论、源代码和数据。
灾难剧场演练流程
每次演练都始于担忧。例如,如果一个园区因为地震,和其他园区发生通信中断,会发生什么?
针对故障引入后会发生什么,建立可靠的稳态假说。将所有专家和感兴趣的人聚集在一个房间或视频会议(包含上下游依赖组件的工程师),有助于缓解混乱。可以邀请管理层参与灾难剧场,得到他们的支持。
演练的准备工作如果没有确认就不要启动演练,它包括:
本次演练的学习目标是什么?如何评估从演练得到的价值?
初期进行灾难实验时,先从小处着手,以尽量小的单元作为目标。再逐步加大规模。
实验安排的时机,是否考虑了特定场景,比如具有潜在意外行为的新特性/新子系统正在发布,新的基础设施正在引入?
在哪些服务区域/机器引入故障,如何模拟故障?实验流量是否足够让故障被检测出来?
针对注入的故障,会发生传递性故障么?会传递到什么范围(爆炸半径)?
可观察性如何保障,仪表盘在哪看?能快速检测哪些告警,日志和指标?推荐指标有线上问题工单数,服务出错率,延迟,自动容量伸缩耗时,资源占有率等。
识别应对故障的冗余和自动补救机制,以及执行手册。
预留充分的演练时间,让所有人能听清指令和讨论。
公开发布演练公告,鼓励关注。让值班同学密切监控。
演练时间通常要错开重大假期和公司各种年度活动的安排。
指定一个经验丰富的主持人来指导混沌工程的全流程。
指定过程记录员,记录故障发生及解决的事件、跟踪行动和时间。
其他可选角色包括:执行命令者,观察者,协调者等。
演练过程须知:
如果发生计划偏移,出现对客户的意外故障,则终止实验。
把演练故障当成真实停机事故一样对待
尽可能一次只测试一个假说,并把自动化反应和人的反应区分开来。注意一个假说也可以是多个故障同时注入的组合。
不要开发使实例失效的新方法,掩盖了现有失效行为的根因。
演练结束时,参会者花一点时间进行即时反思。并在会后为大家汇报演练发现的事实。让更多人了解组织可以使用哪些技术来容忍生产环境的各种故障,为系统可靠性和开发环境质量提出建议。
演练帮助这些不常合作的参会者,朝着改善系统安全性的目标共同努力,当事故真正发生时就能非常高效的协作。
同时,反思我们如何让用户注意不到故障的发生,我们的盲区在哪里?
哪些手工行为可以自动化。哪些行为不能,也不应该自动化?新的自动化除了付出成本,也可能会给运维工程师带来新的任务行动。可高效自动化操作的系统往往是脆弱的,允许低效率有时是个好事,人们有足够的时间针对未预期故障制定补救决策。
演练是系列化的,当漏洞被发现,我们会规划再次演练以验证补救措施是否生效。
常见的灾难测试类型与启发
1 场景一:异常大的流量峰值导致服务的平均延迟,但是不会违背 SLO。
当被服务用户足够多时,哪怕没有承诺的合同,用户也会把稳定服务下的性能看作应当如此(即 SLO-隐形合同)。
2 场景二:非关键后端服务发生故障,不会导致连锁反应失控。
通过大量故障注入测试,尽可能发现关键的依赖关系,建立 “如果失效后发生什么” 的充分认知。
3 场景三:特定网络区域中的计算资源意外丢失。
对于分布式系统,流量高峰达到多少就应该考虑紧急情况的资源分配?确保团队能自如地转移容量和主备切换。
4 场景四:数据损坏时,能从系统的最新备份中还原。
确保恢复过程正确,备份可以正常工作,这个过程是否发生数据不一致问题,如何处理?
5 场景五:区域性的网络故障导致机器离线。
应该从不同大小的规模对网络故障进行测试,通过精心设计的防火墙规则,证明系统的容忍故障能力。
6 场景六:关闭告警组件后,故障注入行为能否被发现?
7 场景七:所有系统都重启,能否尽快重新开机并正常服务?
灾难该如何总结
灾难结论围绕这三种结果来展开分析:已知事件和预期后果,已知事件和意外后果,未知事件和意外后果。
关注出现意外后果时是否有自动终止的能力,是否学到了意外故障的成因,以及从故障中恢复的知识。有些外部事件是系统不可控的,定期操练可以提前预防多数问题。
出现未知事件对团队最有价值,可以帮助我们找到盲点,了解上下游组件产生的累积效,应明确在哪里要投入更多的时间。
混沌工程实验出现的故障,其优先级可以从发生频率,发生可能性,优雅处理该事件的可能性来确定,并和客户期望相匹配。如何确定故障/指标误差是业务原因造成的,还是混沌实验本身带来的。
最后,我们看看团队的教训:
观察团队在实验过程和故障排除中的沟通是否充分沟通?这次实验是否有足够的余量来避免灾难性的故障?
关键角色是否就位?如果无法找到他,团队该如何处理?
人们永远不可能在事故发生前拥有避免它所需要的完备知识,只能对意外持开放态度。
灾难剧场的人为阻力,如何应对?
一,允许业务受影响的团队申请本次灾难测试的豁免。但这个豁免本身就暴露了系统目前的脆弱风险,值得未来深入分析
二,有些业务服务等级长时间处于健康的 SLO 水平,这也有可能是团队不希望上报故障,而容忍短停机事件。对此,灾难测试可以针对他们实施尽量长时间的故障注入,鼓励(逼迫
)这些团队采取行动制定长期解决方案。
长期稳定运行的可靠子系统,拥有工程师对它的深度信任,但一旦真的发生故障,它本身就可能成为巨大风险的载体。
三,某些业务团队强烈抵制混沌工程,担心生产环境损失金钱。
不管是金融机构业务还是生命保健业务,系统都可能发生停机事故。那我们要问对方一个问题:你选择以无法预测的频率和严重程度来对待它,还是采用混沌工程主动了解风险,预防失控?
对于生命至上的医疗领域,医学就是在双盲临床实验上发展的,这就是一种 “混沌工程实验”。
正如墨菲定律所言:凡能出错,必定出错。
混沌工程吸收各个领域的经验教训,可以在各行各业进行探索,受益的也是所有行业。
混沌工程的工具支持
大型技术公司会提供一个共享的、拿来即用的灾难测试通用平台,给实验团队提供方便,这些自动化测试涉及负载均衡,区域任务终止,延迟存储复制,高速缓存的刷新,RPC 的延迟及错误注入等。在 Neflix 公司,这个平台叫 ChAP。
故障注入工具支持的故障模式主要有三种:错误,延迟,超时,以便工程师准确模拟实际生产事故。
平台能给工程师提供 “一键发现请求中涉及的所有服务” 能力,并可以勾选哪些服务要被注入故障,可定期执行并自动发送报告。平台还可以通过 “大红按钮” 一键终止这些自动化测试,快速恢复正常。
好的混沌工具平台,需要对可观测性进行投资,能在仪表盘上让大家更好地了解系统,并提供一些可解释信息,对特定服务/硬件中出现故障的可能性进行排名。
混沌工程平台,和持续验证/DevOps 平台可以深入融合,提供灰度测试比对能力,也提供可视化的实时系统总体状态。在持续验证平台自动运行实验,最大程度提高产生洞见的速度。
未来,持续验证的混沌用例包含性能,数据制品,分层正确性验证(基础设施,业务逻辑,应用三层),这三种类型。
人和组织的能力提升
混沌工程旨在建立一种韧性文化,识别并增强人员和组织的正向能力。
人们在设计混沌实验时,更愿意讨论彼此的思维模式差异,因为安全环境下的实验能消除故障发生时的羞耻感。
很多团队只有在被要求时,或者重大活动(如双十一)来临之前才执行实验,其他时候只有专职团队在做混沌实验。为了打消大家的顾虑,构建一个安全的混沌工程平台非常重要,需要混沌平台开发者和用户(产品经理和工程师团队)的深度交流,包括这些问题:
了解各团队的设计实现机制:超时,重试,调用回退,定期服务的流量百分比等等。
你对系统各种配置参数设置是否有信心?哪些日常操作最让你害怕。
当你的服务出问题,如何影响上下游服务?
你的系统(包括上下游),最近是否可能引入新的漏洞?
通过以上的访谈,讨论清楚混沌实验的范围和四大步骤,达成共识。
对于一个组织本身,混沌工程的精神也能提升组织的韧性。比如把一个工程师抽调到其他团队工作一段时间,等同于给系统注入了故障,经常性的训练能够让组织更加适应人员切换,承载挑战的能力更强,员工也获得了更多的跨团队技术经验。
Casey Rosenthal 描述了一项 “疼痛紧身衣” 的思维实验:把基础设施捕获的风险信号转换为穿戴者皮肤的疼痛感觉,比如早上醒来,感觉左肩膀痛,你就会想,微服务 X 又在胡闹了。这套衣服穿一段时间,你很快就对整个服务情况有直观的理解了。
但是疼痛紧身衣和混沌工程的目标并不相同,前者只是反应本能,并不能转换成可传播的知识。
混沌工程能够增强只有人才具有的灵活性和上下文相关的判断力,人最擅长的是就是提供解释。
人总是要做软件的 “决策”,因为人能负责,而软件不能。