一、背景
随着货拉拉微服务架构、容器化技术广泛使用,软件架构的复杂度在不断提升,由服务之间的依赖所带来的不确定性也呈指数级增长。在这样的依赖网中,任何一环出现非预期或者异常的变化,都可能对其他服务造成非常大的影响。
因此,我们通过构建一个故障演练体系,来提升系统架构的容错能力和韧性,也可以站在未知故障视角来验证系统稳定性,验证整个故障定位能力和恢复体系。同时可以以战养兵,提升故障应急效率。
二、体系全览
目前,货拉拉故障演练体系主要包括管理体系、工具体系、运营体系:
我们在建设该体系之初,是想通过故障演练建立研发面向失败编程的思维,配合故障演练提前探知系统风险,并通过架构优化来解决优化系统风险,从而真正提升架构容错能力,并实现韧性架构,降低由于故障带来的损失。
在这过程中,我们锻炼了故障应急同学解决故障的能力、并验证了应急流程、应急手段、监控报警有效性等。
- 管理体系,通过制定故障演练SOP,从技术角度制定在故障演练实施过程中的操作规范,避免因人为操作可能引发的系统风险,以及当风险发生时的应对措施。
- 工具体系,围绕预防、发现、恢复、复盘、改进这5项关键点展开的故障演练工具体系的搭建。
- 运营体系,从演练评价、机制文化、组织建设等各方面构建起货拉拉演练生态。
三、工具体系
货拉拉故障演练平台现阶段主要在全局攻防演练,日常故障演练等应用场景;主要模块有应用管理、故障中心、机器管理、演练经验库、运营统计等。
故障演练平台的总体架构如上图所示:
- 应用管理,维护应用相关元数据,包括应用名称、部署类型等信息。
- 故障中心,支持Java应用、中间件、系统资源等故障类型;并在故障生命周期中提供故障下发、故障恢复等能力。
- 演练经验库,将成熟的演练方案、演练场景纳入经验库,保证了场景真实性;针对通用的演练场景,可以提升创建演练的效率。
- 运营统计,通过更直观、更具业务价值的数据来帮助我们提升系统稳定性。主要运营数据有演练数据、预案数据、改进项等。
以上是故障演练平台目前支持的能力,如图所示:
- 从支持的场景来说,主要支持攻防类、功能类(监控、资损、预案等)、混沌工程三大类场景。
- 从故障类型来说,主要是Java应用、中间件、系统资源和基于业务场景维度的故障。
- 从爆炸半径控制角度来看 ,分别提供了流量隔离策略、环境隔离、业务标识、控制命中次数等方式。
- 在混沌工程方面,提供业务链路/应用间强弱依赖关系的能力。
故障中心在整个体系中主要承载了故障编排、故障下发、故障恢复能力。在平台性能方面,支持单机每分钟1000+节点的故障注入,完全满足公司级别全局攻防演练和日常演练需求。
基于故障场景的流程编排,我们可以通过多场景 + 多故障的方式自由组合,如上图。
通过流量隔离策略,能满足我们90%以上控制爆炸半径的诉求,目前有以下三种策略:
- 自定义标识隔离策略,指定单个/多个自定义的流量,适合故障需要隔离部分流量。
- 灰度隔离策略,指定单个灰度版本内的流量,适合在正式节点获取灰度标识信息(精准使用真实用户流量)。
- 多泳道隔离策略,指定单个泳道内的流量,可以满足针对某些城市一定比例的用户、司机注入故障。
流量隔离策略流程如下:
当我们做常态化演练时,需要考虑的一个问题是ROI是否合理。每次演练或多或少都需要人工参与,继而耗费人工成本。当我们常态化演练之后就需要考虑自动化,替换人工投入成本。
其次混沌工程其实是一个防御性的工作,它要求覆盖面全,如果每个关键点上的性价比不高,那么全局损耗将非常巨大。
因此,我们的目的非常明确,第一点,减少人工成本,并将覆盖面最大化;第二点,以发现问题为目的,定时定期自动演练。
演练自动化关键因素:
- 爆炸半径控制,演练自动化无人值守,因此对爆炸半径控制更为严格。目前确定的隔离策略是指定测试流量在线下稳定环境运行。
- 服务依赖关系管理,演练自动化旨在梳理两两依赖之间的强弱关系。首先,我们要拿到准确的依赖信息,如,核心链路上,服务之间、接口之间、服务与中间件之间的依赖信息。
- 故障编排,不同于常规故障演练。演练自动化的编排策略主要有并行、串行、手工控制。
- 熔断能力,熔断能力是演练自动化最重要的能力之一。在对目标服务注入故障时,根据监控数据判断是否立即熔断。
- 验证流量,验证强弱依赖关系最重要的判断依据是验证流量。验证流量可以分为自然流量、测试流量、回放流量等。通过端到端的自动化作为验证流量,能最大程度上满足需求,并且投入成本低。
四、管理体系
通过制定演练策略和故障演练SOP,来界定各个演练类型的边界,并从技术角度制定在故障演练实施过程中的操作规范,规避因任务操作可能引发的系统风险,以及当风险发生时的应对措施。力保避免因故障演练实施过程中对真实业务产生的影响。
根据目前演练目的不同,区分为故障演练、全局攻防演练和混沌工程三大类。
一次有效和高质量的故障演练,会涉及到方案梳理、故障注入、观察、问题记录、恢复、复盘等。流程如下:
过程中主要有以下几个阶段:
- 计划阶段,演练方案(包括强弱依赖关系、应急预案、目标应用、故障类型等)、演练事件、爆炸半径控制等。
- 执行阶段,演练过程中监控报警是否有效、应急预案是否生效;观察故障影响范围并及时反馈,有问题及时终止演练。
- 恢复阶段,恢复故障注入,应用重新发布。
- 分析阶段,收集故障演练中过程数据,如应急时效、预案执行后是否符合预期等;产出演练报告和优化项,优化项完成后再次通过故障演练验证。
五、运营体系
故障演练在货拉拉的落地实施,总结下来主要分为三个阶段。
这个阶段主要探索验证为主,主要验证流程规范、平台能力等。通过小范围的试点,培养目标团队的心智,并同时拿到一些明显的收益,方便后续扩大试点范围。
- 试点范围主要集中在核心业务团队的非核心场景,目的在于验证故障演练的可行性。在各方建立了足够的信心后,再扩大试点范围。
- 演练场景优先选择历史发生过的故障,生产发生的故障,很有可能再次发生。通过复现历史故障,验证历史故障是否被修复以及验证应急预案有效性。
- 演练环境的选择,从线下环境着手逐步转线上是相对稳妥的选择。
- 爆炸半径则是通过测试流量 + 单接口 + 单节点的方式控制。
经历了上一阶段的能力验证,将试点范围逐步放大到各个业务团队。其次组建了专门的故障演练团队,旨在帮助业务团队更好地落地。这个阶段主要是获取更多的数据样本,发现更多问题(业务、流程、工具平台等),为后续常态化奠定基础。
- 试点范围扩大至各个业务团队,通过课程分享、部门推广会等方式,培养研发同学心智,获取更多数据样本。
- 演练场景主要以历史发生的故障、相似链路上的历史故障类型为主,历史发生的故障很有可能在其他链路上也发生。
- 在演练环境方面,故障演练平台逐步开放线上灰度环境的演练。通过线上演练审批流程、发布窗口、封网窗口等方式筛选线上演练场景。
- 在爆炸半径控制方面,主要以单应用多节点、单应用单节点、测试流量等方式控制爆炸半径。
- 演练时间主要推荐工作日晚上低峰期开始,这个时间段,相关同学保持oncall,任何情况都能及时处理。
- 工具平台建设方面,主要实现自动化演练、自动化收集演练数据、高效管理演练场景等。
- 结合CI团队,以验证预案有效性为目的,演练平台作为验证预案有效性的唯一手段,进一步增加平台用户粘性。
- 在活动运营方面,每月/每季度定期举行全局攻防演练,提升品牌效应。
该阶段故障演练范围覆盖了全部业务部门,演练流程、平台等方面也比较成熟;各部门已经具备自主演练能力。
- 运营策略主要通过公众号、客服群等方式提供给用户一个了解平台新功能和日常沟通渠道;并且通过全局攻防演练和故障演练积分制等机制激发全员参与积极性。
- 演练场景主要以主链路核心场景,定期、随机发起演练。
- 沉淀出各个业务部门故障演练最佳实践,作为系统稳定性保障的重要一环,各个部门自行组织常态化演练。
- 平台建设方面,主要开放演练自动化、监控报警验证能力、资金内控验证能力等主要功能,进一步支撑常态化演练。
- 心智方面,从被动接受故障演练到主动尝试实验;从验证监控报警、预案有效性到主动发现系统稳定性。
- 正向收益和价值明显,持续提升运营关键指标(各业务团队故障演练数、预案验证数、改进项等),有进一步支撑持续运营的动力。
- 目前在公司内部实施故障演练的过程中,支撑了10+业务部门演练需求,分析了900+演练场景,通过每月800+的频次开展常态化故障演练,有效发现了100+问题(不局限于监控报警、应急预案、应急流程、系统强弱依赖等);
- 故障演练管理体系的搭建,规范线上演练流程,避免因故障演练引发的线上故障;
- 定期举办的攻防演练,不仅锻炼了故障应急响应团队的应急能力,还间接提升了系统稳定性。
六、未来展望
最后,展望一下故障演练体系未来的规划,主要从演练成本、故障多样性、演练过程观测能力等几方面展开:
- 丰富故障类型,建设业务链路级别故障、支持更多语言(c++、go)。
- 降低演练成本,比如演练场景选择、故障调试等。
- 进一步完善可观测能力,多视角多维度观测目标系统、链路