做了两年多的故障演练, 一直想聊聊自己对故障演练的理解,但是每次提起笔都不知道写一些什么。
什么是故障演练
为什么要做故障演练
在没做故障演练之前,我想很多人可能和我有一样的想法,我的系统跑了好多年,也没出什么问题,认为自己写的代码挺牛逼的,稳定性贼强。但是做过故障演练之后就会发现“什么垃圾东西”。
故障演练的演练场景非常广泛,小到代码,大到机房。能够覆盖绝大多数故障场景。如:
- 磁盘读/写满载故障,验证应用在磁盘高负载情况下的容错能力(如:磁盘满载导致服务 rt 升高。)。
- 网络抖动故障,验证在网络异常的情况下应用的容错能力(如:服务无法链接数据库)。
- 方法异常,验证代码异常情况下服务的纠错能力(如:数据库查询异常)。
- 方法抛出异常,验证核心方法异常后的容错能力。(如:创建订单抛出异常)
- ……(基础故障见下图)
如上,通过故障演练不单单可以验证代码层面的异常,也可以检测磁盘、网络等各种异常场景下服务的容灾能力并验证预案是否有效。保障我们在真实故障发生时能够从容面对,并高效解决问题。
历史事件
如何做故障演练
故障注入时机
根据故障发生过程分为前,中,三个阶段
- 故障发生前(验证在故障发生时应用的可用性)
- 故障发生中(红蓝对抗 之 给故障填一把火)
- 故障发生后(故障复现)
故障发生前 - 故障验证
在绝大多数场景下进行的故障演练都发生在故障发生前。流程大致如下
- 对可能发生的故障进行分析,输出故障类型、故障预计影响范围。
- 故障编排 编排故障,(需要多个故障的场景,组合多个故障)配置故障目标
- 故障注入
- 观测故障注入后对应用的影响。(如关注 avgRt,maxRt,errors,tps 等各种指标但根据故障的不同,验证内容的不同观测的指标也不尽相同,需结合实际场景。)
- 撤销故障
- 验证故障撤销后应用是否恢复 输出故障报告(故障实际影响范围,预案是否生效、撤销后是否恢复等数据)
- 项目优化
以上是一个基础的故障注入流程,比较重要的是:
- 一定要在故障注入前先评估故障影响范围,因为有些故障是不可逆的,可能造成不可挽回的损失,比如你注入了一个 cpu满载、磁盘满载故障、或者网卡网络延迟故障,这些故障都可能导致故障无法撤销,只能通过 reboot 。
- 确定本次故障注入是否有意义,防止做无用功。盲目的进行故障演练并不会提升系统的稳定性,健壮性,只会增加负担。
- 故障撤销后故障并未结束,确保故障撤销后应用恢复。
故障发生中 - 红蓝对抗 之 给故障填一把火
这部门内容也扔在探索进行中,以下是本人的一些拙见。
红蓝对抗这个概念因该也并不陌生,在军事上进行红蓝对抗验证军队攻守能力、现代化作战能力等,在互联网行业,同样可以进行无硝烟的红蓝对抗。
(注:红军为进攻方,蓝军为防守方。不同公司对红蓝的定义并不相同)
故障演练只能作为功放,也就是进攻方搞破坏的一方。
作为一个合格红军的标准:
随时 - 注入时间随机
随地 - 注入目标随机
随机 - 注入故障随机
根据以上定义,其实总结下来就一个字 坏。
以上是我设计的一个比较简单且容易实现的流程,第一部配置一个故障池一个目标池,然后开始任务接下来全都交给随机数。在这个流程下故障注入的影响范围是不可控的,就达到了足够坏的目标。但是同样因为是不可控的所以存在故障注入过度,也存在故障注入达不到目标的风险。
如果通过增加逻辑做限制的方式到最后就像一件乞丐服缝缝补补。
探索中后续有进展再跟进
故障发生后(故障复现)
这一部分就不想详细介绍了,几乎没遇到过通过故障注入复现故障场景的情况。
强弱依赖
//TODO
开源工具
chaosblade
//TODO
chaosmesh
//TODO