考虑”数据篡改“类的故障,可能会导致写脏数据,尤其是篡改业务执行主体(如商户 ID、用户 ID)写脏真实业务数据的风险,因此禁止”篡改执行主体“的故障。
考虑执行的实验的风险,我们对这些场景加了审批:
“修改”类的故障加审批。避免写脏异常影响真实环境,由leader二次评估确认。
非资源负责人执行审批。如对他人模块实验(模块混部对母机实验校常见),避免无法发现其它业务异常。
非工作时间实验审批。避免实验异常,干预时间长。
2.1.2 有效:贴近真实环境我们主要在隔离的混沌分区实验,实验环境与真实环境一致性越高,真实环境出现类似的问题概率就越大。静态:部署环境的一致性部署环境一致性的主要维度如下:维度一致性需求应对方案地域高同地部署园区中多园区部署,随机选择园区机器实验机房/交换机/机架低对上层相对不透明,且可实验空间较小(爆炸半径过大),项目未要求机型中较少涉及此类差异的故障,线上基本一致,项目未要求操作系统中容器高一致的容器版本,一致的容器规格二进制(代码)极高统一部署,完全一致配置极高我们将上述高一致性要求的地域、园区、容器、二进制、配置,做到 DevOps 部署工具中,上线模块、发布变更时做到与投产环境一致。动态:实验流量的逼真度实验流量与线上接近的目的,一是还原机器/容器负载情况,二是还原业务执行的分支,两者在某些复杂组合场景下,是否会触发未知风险。我们从两个维度来评价流量仿真程度:流量指标基本要求更高要求场景覆盖率核心链路覆盖线上所有依赖服务接口请求并发度平均或峰值 TPS1. 贴近线上各类场景的流量比例
2. 贴近线上随时间波动的流量曲线
基于这两个指标,有两个不同方向:流量类型建设方法优点人造流量基于业务用例与规则,开发执行脚本1. 开发简单
2. 流量可控性强
流量回放线上录制,替换并重建资料类数据,mock 边界调用,mock 随机数、时间等系统调用等1. 流量与线上一致性强、丰富度高
2. 后期新增场景的投入成本低
考虑前期建设成本和不确定性,我们选择了人造流量方案。 2.2 高效、全面的发掘风险从0到1建设混沌工程系统和业务落地,我们遇到了这两类问题:工具业务零基础,优先做哪些故障原子?先建设故障原子,还是先提升实验效率?如何优先找出高风险?用什么方法找全风险?是否可以少投入,甚至不投入就可以完成混沌实验?我们选择从业务目标出发,优先看高价值的风险点,工具配合业务目标逐步丰富故障原子。根据不同阶段的侧重点,将项目的实施路径拆分两个阶段: 2.2.1 发掘高价值风险前期,人力、工具有限的条件下,如何发掘高价值风险(高 ROI)?较简单的方法是:随机注入。工具团队可根据近几年的故障类型,按照优先级开发出对应的故障原子,无差别的注入到目标模块。当前期自动注入、稳态分析不够健全的情况下,仍需人工参与,这种方法有2个局限:实施的业务团队人力投入大:人工注入故障,人工观察、分析业务监控,以及监控偏离时是否影响业务、是否会扩散风险、是否有其他潜在风险;工具团队不能做到有的放矢,不能将有效的人力投入到最有价值的原子开发上来。为了快速找到高价值风险,进而提升大家参与的积极性,我们选了如下2个策略:实验对象从 高价值 往 低价值 覆盖。根据这个思路,得到了优先实施的模块。1)公共组件:RPC 框架、队列、存储 、缓存,安全认证、日志等;2)生命线业务:收付结退。基于高可用原则拆解,得到工具待开发的原子需求和待注入的资源。设计路径如上图,根据历史故障和常用的高可用要求原则,假设某个组件/业务满足该高可用原则,根据该原则拆解到需注入的故障原子和注入范围(靶点),某个业务或组件待实施的混沌实验计划如下图:通过这些策略,我们快速的找到 HTTP 接入模块、事件中心、跨城组件等微信基础组件的多个高风险的共性问题。 2.2.2 找全风险后期,如何增强覆盖面,发掘更多未知的黑天鹅风险?上述方法,只能覆盖到有限的故障域,而实际故障往往是由多个事件同时发生而触发,因此后期加强单原子无差别的注入和组合故障的注入可以发现更多中长尾问题。对于组合故障,如果也是无差别策略,那么组合空间极大,就以微信支付委托代扣业务为例:单故障注入:18模块 * 15个故障原子 = 270个,即单原子无差别的注入次数;2个组合空间为 C2270 = 36315,任一组合空间为2270。即使工具已经具备自动注入、自动分析的能力,实验周期和消耗资源也将会很高,因此合理的剪枝很有必要,可采用基于相关性由强到弱的多故障组合,如:模块内构成依赖关联影响(包括三园区容灾设计);业务内模块间依赖关联影响;业务间依赖关联影响;基础设施间依赖关联影响;潜在依赖关联影响。 2.2.3 自动化从实验流程来看,除了“修复问题”,另外三个流程可以做到一定程度的自动化。自动设计一个实验任务由4个部分组成:
业务资产:集群、模块、接口;集群是多个模块的总称,如某个存储集群包括接入模块、存储模块、元数据模块;
系统资源:业务资产执行所依赖的机器、容器、网络、CPU、磁盘、进程、文件、内存、共享内存等;
故障类型:针对每种系统资源的有多种故障,如机器包括机器重启、机器时间错误等,如网络包括慢、丢包、乱序等。
故障程度:除个别的像机器重启这类0-1类型故障,其它大多数涉及一定程度的故障,比如网络丢包30%,不同程度下的表现略有不同,一般将故障程度拆解成几档,如丢包有单机内10%、30%、50%、80%、100%,再组合多机情况。
一个实验,首先圈出所包含的业务资产,再整理出其依赖的系统资源(除了磁盘、文件、共享内存这几项,其它一般都包含),再展开系统资源的故障类型,最后确定故障程度,有两种策略:
标记资产类型,如标记为某类存储集群,则套用已设计过的实验模板库生成实验任务;
标记业务所适用的高可用原则,如单机/园区剔除能力、异常防御、分区切换、旁路冗余设计等,裁剪掉全展开的无效程度值,如单机剔除原则只容忍下游单机或单园区机器故障所以不生成多机故障,而做了旁路冗余设计的业务则容许旁路模块的所有机器故障所以生成单机故障的必要性就不大。
因此业务需要做的是:圈定资产范围及依赖的系统资源,并标记资产类型或适用于哪些高可用原则,便可自动生成实验任务。
自动执行
系统建设不是一蹴而就的,从手工执行到自动化我们经历了三个阶段:
手动执行单个故障,主要解决0-1的问题,主要精力放在故障原子建设上;
单次批量执行多个故障,采用 yaml 文件记录编排方式,支持串行、并行调度。应用于业务首次实验和定位问题。
定时执行/事件触发执行,主要用于变更回归和可用性巡检场景,因为定时执行也依赖后续的“自动分析”,所以放在最后。
自动分析
上述自动执行减少了“点击”操作的工作量,实验要”完全“自动化,还要结合自动分析,即自动判断是否偏离稳态。一是当稳态偏离正常范围及时停止,避免造成次生灾害;二是只有做到自动分析,才能低成本的“定时执行”,否则每次自动执行后都依赖人工分析,不可持续。
我们根据实验的时间(实验开始时间到实验结束后一个周期),自动匹配与之相关的稳态告警:
业务:业务用例维度监控是否触发告警。强优先级,触发后停止实验。
模块:上下游调用关系是否出现告警。中优先级,触发后不停止实验,展示在实验报告中。
IP/容器:机器和容器是否出现资源异常告警。中优先级,触发后不停止实验,展示在实验报告中。
业务自定义监控,上述无法自动覆盖的监控,由业务配置后自动收集。
2.2.4 风险处理发现的风险的除了负责人处理外,方法:
个性问题:周知组件、业务负责人处理
共性问题,通过 SOA 治理、架构模式化、完善研发流程等手段来大规模消除,达成组织价值最大化。
对不同时期出现的问题采用不同的策略:
存量:采用了 SOA 治理平台推动修复(SOA 治理是微信支付风险和异常项治理的平台,提供了统一的异常接入、展示、周知、跟进管理的指标数据,在部门内形成了统一的风险治理共识,以快速治理、收敛风险。混沌工程将发现的风险接入 SOA 治理平台,快速治理大面积的共性风险)。
新增:通过 MR 流水线门禁和变更门禁堵住新增,需处理后才能通过。
03成果我们通过一套流程推进:设计实验(建设原子) - 执行实验 - 分析结果(挖掘问题) - 修复问题,在业务风险挖掘和工具建设上都取得了不错的效果。 3.1 业务成果2021年上线至今,线上0故障,执行实验计划60+个,实验任务500+次,覆盖业务、框架、组件多类场景,并发掘多处风险。 3.2 工具建设成果微信支付从0到1建设了混沌工程系统(由业务连续性架构中心和支付运维组建设)。已支持30+种故障原子,典型原子:页面支持拖拽式编排、串并行编排,并可配置定时启动实验用于常态化验证风险。通过关联微信支付的模块调用异常告警、业务监控告警,识别正在实验的模块/IP 潜在异常,在实验报告中展示出来,提高实验后分析效率。04总结与展望 4.1 总结本文从业务角度,介绍微信支付实践混沌工程落地的思考,通过多分区的架构来控制最小爆炸半径,首先在高价值的基础组件和微信支付核心业务场景上探索,并基于高可用原则、历史故障分析推导故障原子的开发。发现了多处共性风险,并推动修复和治理。 4.2 展望 4.2.1 更丰富的故障原子建设有效性和安全性始终是一个权衡取舍的因素,如前文介绍,微信支付在独立的混沌分区架构中实施,前期使用仿真流量,因此除篡改数据类的原子外,在控制请求量的情况下,注入故障的爆炸半径很小、对线上影响极低。
但出于业务安全的思考惯性,我们在建设故障原子时基本是按照演习的思路建设:先摸清组件原理,逐个组件/业务定制原子,导致前期交付周期较长。若在控制爆炸半径的基础上,开放更多故障注入的自由度,注入更多、强度更大的故障,可以低成本的发现更多有价值的风险。
4.2.2 自动化与稳态识别自动化包括:注入故障和异常判定,当前系统支持了注入故障的自动化和简单的稳态识别,识别的正确率和召回率还有空间,因此异常判定大多数仍需人工分析。自动异常判定需要较为高级的 AI 能力,很难基于某些特定规则覆盖所有场景。若能做到全面的自动化,其它业务便可低成本落地混沌工程。另外,也可以注入大批量的组合故障,探索更多未知风险。 4.2.3 支持多类爆炸半径的实验本文在多分区上部署独立的混沌分区,来控制爆炸半径。而对于非核心支付或者非支付的大多数业务,并没有多分区环境,因此要在其它业务实施混沌工程,仍需结合业务安全和有效性来取舍。-End-原创作者|刘斌本文由高可用架构转载。技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿