作者:乔桃利|QE_LAB
混沌实验是通过对系统注入故障来模拟现实世界,探索发现复杂分布式系统暗债,推动改进系统韧性设计的探索实验。通过在生产环境持续开展混沌实验,提升团队修复故障的效率和能力。混沌工程发展到今天已提炼出完善的实验步骤、实验原则、成熟度标准等,业界也开源了多款故障注入工具,让混沌实验可模拟的故障类型更加丰富。虽然有混沌工程理论和故障注入工具的支撑,但是团队在组织内实践和推广混沌工程时,仍然会遇到不少痛点。
以之前参与的 A 项目为例,该项目的混沌工程实践、推广由数据中心部门发起,混沌实验主要由测试中心的测试人员完成。在实践过程中,遇到了如下痛点:
1)业界故障注入工具可以注入的故障非常多,如何选择优先注入哪些类型的故障呢;
2)可注入的故障间可能有重叠,例如 CPU load 和 Memory load,也许模拟的现实世界故障影响结果一致,需要重复注入么;
3)发现了某些系统暗债,但是测试人员难以驱动开发人员尽快修复;
4)已经开展的实验聚焦在基础设施层,业务应用层的混沌实验很难开展。
同样,参与的 B 项目在混沌工程实践方面也遇到一些痛点。B 项目背景是混沌工程实践、推广由开发中心发起,混沌实验由开发中心的专项测试人员完成。在实践过程中,遇到的痛点如下所示:
1)混沌实验更多从可以注入的故障出发去设计实验场景,如:注入 Pod Failure,看 Pod 是否能重启成功等,探索到的系统暗债有限;
2)专职混沌实验人员对业务系统逻辑不清楚,开展的实验有限,功能测试人员又难以直接开展混沌实验;
3)混沌实验主要聚焦在业务系统层,对于基础设施层,几乎难以开展实验。
分析两个项目所遇到的痛点,会发现两个项目虽然来源于不同的组织,但遇到的痛点有共性。A 项目中遇到的痛点 1、2 和 B 项目中的痛点 1、2,虽然表现形式不同,但本质上都属于 “如何更好地设计混沌实验” 的问题。A 项目中遇到的痛点 3 属于 “如何让混沌实验得到闭环” 的问题。A 项目中遇到的痛点 4 和 B 项目中痛点 4 本质上都属于 “如何推动跨部门人员开展混沌实验” 的问题。两个项目遇到的痛点和分析结果如下图总结所示,本质上要解决混沌实验设计、实验闭环、跨部门协作三个问题。
对上面要解决的三个问题进一步分析,先来看为什么混沌实验场景设计不够理想,根因在于两个项目都是由专职测试人员在设计和实施混沌实验。由于角色分工和知识体系原因,专职测试人员对于系统已有的高可用设计了解有限,不能从系统高可用设计出发来设计实验,而是从可以注入的故障出发来设计实验,这就造成设计的实验,可能存在稳态假说不完善、实验探索目标不清晰的问题。而为了设计出有价值的混沌实验,必须依靠团队多角色参与,至少包括熟悉系统高可用设计的开发工程师,熟悉业务系统用户旅程的测试人员以及熟悉基础设施高可用设计的 DevOps 人员参加。只有通过多角色共创才能设计出探索目标明确的混沌实验。然而,不同角色在某些组织中可能属于不同职能部门,角色间沟通本身存在一定壁垒。通常情况下,组织结构不会做大的调整,在这种制约条件下,如果有一种方式能创造不同角色间持续沟通的环境,就能解决多角色共创的问题,而将混沌实验内建到持续交付过程中,即可解决这个问题。因为即便在按职能划分的组织中,也会基于交付目标形成一个多角色的虚拟小组来按时完成项目交付,这个虚拟小组下包括开发、测试、运维 DevOps 等角色人员,这些角色间为了交付目标,会持续沟通,天然就建立了持续沟通的渠道。所以,将混沌实验内建在持续交付过程中,可以减少角色间或者部门间的沟通、协作壁垒,便捷的共创混沌实验。
接着再来看第二个问题:混沌实验得不到闭环。在 A 项目中,因为混沌工程的推广是数据中心发起,而混沌实验实施是测试中心测试人员,再加上混沌实验发现的一些技术暗债,和直接的功能需求相比,优先级可能会降低。所以,由数据中心或者测试中心跨部门推动开发中心人员尽快修复系统暗债就困难重重。而将混沌实验内建到持续交付过程中,可更早的发现系统暗债,在后续迭代中就可以尽早实施改进措施。
再来看第三个问题。当混沌工程由数据中心发起时,混沌实验主要聚焦在基础设施层;当混沌工程由开发中心发起时,混沌实验主要聚焦在业务系统层。如果把混沌实验独立成专项测试,在某个时间段由专一角色完成,要推动跨部门的协作开展混沌实验是非常困难的。而如果将混沌实验内建到持续交付过程中,会自然改为由项目驱动的方式。如果负责的项目属于业务系统,那么混沌实验场景重点在业务系统上;如果负责的是基础设施平台,那么混沌实验场景重点在基础设施层。对于某些更大范围的混沌实验,需要多团队协作配合的,也可以由项目驱动方式完成。这就和多个项目需要联调一样,当把混沌实验内建到持续交付过程中后,大范围的混沌实验放入联调计划中则可较容易的开展。
总的来说,针对三个问题,将混沌实验内建到持续交付过程中,就可以依托持续交付过程中建立起来的多角色虚拟小组,顺利开展多角色共创混沌实验场景的 Workshop。当业务系统、基础设施平台进行高可用设计时,同步开展混沌实验,尽早发现系统暗债,这样利于将改进方案安排到后续迭代中尽早实施。同样,有了项目为驱动的虚拟小组,跨部门角色的协作也会更加容易,因为交付项目都存在多系统联调问题,大范围的混沌实验可以直接沿用多系统联调建立的沟通渠道、机制,降低沟通、协调成本。下图是精简总结的 “为什么建议将混沌实验内建到持续交付过程”,具体内容如下所示:
上面分析了 “为什么建议将混沌实验内建到持续交付过程中”,那具体该如何在持续交付过程中开展混沌实验呢?首先,在需求分析阶段,可以基于业务系统或者基础设施平台的需求,建立初步的混沌实验稳态假说,重点关注系统高可用设计相关的需求。接着,可以基于稳态假说,补充实验前置准备、实施步骤、实验结果观察点,并把这些内容可视化。例如可以和业务需求一样通过 JIRA 卡片管理。然后,当真正实现需求时,还会对需求进行详细的 review,这个时候可以同步 review 混沌实验是否还有细节需要补充。当这些工作都完成后,即可在测试环境下开展混沌实验,对于是否在生产环境开展同样的实验,可基于项目实际情况抉择。具体流程上的步骤如下图所示:
上面只是从流程上讲解了混沌实验如何内置到持续交付过程中,接下来通过一个具体的例子,实例化的方式来看看如何去实践。下图是 B 站一次高可用设计分享中的例子,左下图是分享中简化版系统架构图,右下图是分享中给出的负载均衡的高可用设计点。假设以这个为混沌实验对象,来看看如何针对里面的高可用设计点设计混沌实验场景。
以数据中心负载均衡的高可用设计第 2、3 点为例,当基础平台计划实现这个功能时,在需求分析阶段,即可根据要实现的高可用能力,由负责高可用设计的开发人员主导产出初步的稳态假说。
接着,当高可用设计需求全部细化完成,并排入待处理事项后,混沌实验也需要进一步完善前置条件、实验步骤。实验的完善过程需要开发、测试以及运维人员共同参与。因为测试人员熟悉业务系统流程,善于通过性能测试工具调用服务接口完成生产业务流量模拟的任务。稳态假说需要从高可用设计出发进行分析,自然离不开实现高可用的开发人员。此外,服务是部署在集群中的,在实验执行过程中可能需要关注监控系统、告警系统、日志系统,并且在使用公共三方系统过程中遇到问题,或在对集群中系统注入故障遇到问题时,都需要运维人员协助分析解决。下面是在稳态假说的基础上进一步完善的混沌实验。(备注:因为上面的高可用设计也是粗颗粒度的,所以混沌实验描述相对较粗,实际项目中应该会更详细。)
产出混沌实验后,即可将其放入到项目的迭代安排中同步开展。在系统需求具体实现前,如果有细节调整,那么需要同步 review 混沌实验,查看是否需要做相应的调整。待系统需求实现后,即可在测试环境中,由某一角色(例如可以是测试人员)按照设计主导执行实验。如果发现问题,可以引入开发、运维共同分析。如果确实是系统暗债,那么可以让开发设计优化方案,并尽早排入后续迭代中实施。
综上,混沌实验场景的设计非常关键。这里包括实验对象的选取、注入故障的类型、稳态假设设定等等。这些信息的输出需要多角色共创才能完成。而将混沌实验内建到持续交付过程中,可以借助交付过程中的关键活动,例如在需求梳理阶段、需求实现阶段中完成混沌实验场景的详细设计。混沌实验的实施可以由项目中的某一角色(例如测试人员)来主导完成。当发现系统暗债后,引入其他角色共同讨论改进策略,并将改进方案放到后续交付迭代中,这样可保证整个实验的闭环。当每个项目组针对各自的系统积累丰富的混沌工程实践经验后,再依托交付项目已构建的多系统联调沟通机制,可以使跨项目组或跨部门的大范围混沌实验变得更加容易开展。