从故障制造到混沌工程
系统稳定性是当前任何一个系统都会面临的首要任务,一个不稳定的系统没有任何一个用户愿意使用。这里说到系统的稳定性,就不得不说一下 SLA(service-level agreement),也就是服务等级协议。在 SLA 中比较常用几个 9 来衡量提供服务的稳定性,那么越多的 9 就代表团队要提供的服务稳定性越高,故障时间越短。下面可以简单地计算一下,如果某团队提供的服务满足 4 个 9,那么一年发生故障的时间可以通过如下方式计算:365 天 24 小时 0.0001 = 0.876 小时,也就是 52.6 分钟,更何况当前很多公司的服务都是 5 个 9 的要求,那么故障实践就是 365 天 24 小时 0.00001=0.0876 小时,也就是 5.26 分钟的故障时间,这么苛刻的条件让就在不断的促使团队寻求提高系统稳定性的方法,来满足系统稳定性的要求。
为了保证系统的稳定性,测试工程师可谓想尽了办法,除了常规的测试以外,还会通过在测试过程中创造一些故障,来验证系统的一些可靠性保障机制是否有效。虽然没有现在这么自动化、智能化,但是也同样做的故障模拟的测试,例如要验证测试 A 服务的多活部署是否有效,需要测试工程师进入机房把一台服务器的网线拔掉,来验证服务是不是可以继续对外提供服务;还有如果需要模拟 CPU 负载过高观察系统服务的响应,就要登录服务器后写几个 C 语言的死循环,从而让 CPU 满载;再有为了产生大量的磁盘 IO,通过 dd 命令做虚拟文件系统的镜像文件等等一系列有破坏性的操作,但是这些操作在现在来看,还不能严格地说算是稳定性测试,只能是故障后服务验证。为什么这么说呢,因为当写死循环占用服务器 CPU 资源的时候,测试工程师已经知道问题就是 CPU 资源被占用的原因,也就说测试工程师使用了特定的方法去验证了系统在可能发生类似故障下的反应。而混沌工程是通过多元化的业务场景建立基于场景的故障,它是一种提高技术架构弹性能力的技术手段,终极目标就是将所有故障都在消灭在用户感知到之前。通过主动制造故障,收集系统在各种压力下的行为,识别并修复故障问题,降低技术风险,避免造成严重后果。混沌工程是在分布式系统上进行实验的学科,目的是建立对系统抵御生产环境中失控条件的能力。下面举几个混沌工程的输入例子:
- 模拟云服务机房故障无法访问
- 模拟某地数据中心故障无法访问
- 生产 Redis 数据丢失
- 某类服务响应超时
- 强制系统节点间的时间不同步
- 在驱动程序中执行模拟 I/O 错误的程序
- 让某个 Elasticsearch 集群 CPU 超负荷
混沌工程是一门学科,它提供了基本的理论指导,而故障演练是混沌工程的具体实践,通过向目标系统注入真实可能发生的故障来考量系统的稳定性。
故障演练的实施要点
混沌工程为稳定性验证实验提供可实践的指导,可见如果要将混沌工程落地实践最基础的就是要有一个快速、方便的故障注入工具,然后再结合混沌工程的理论进行故障演练,从而提高系统的稳定性。
- 1 选好混沌工程的工具
工欲善其事必先利其器,选取一个好的混沌工程的工具会对测试工程师来说可谓是工作事半功倍。开源的混沌工程的工具有很多,站在团队的角度选取的工具要是平台化的,作为故障演练的统一入口,需要提供方便、易用的交互方式,能够自动完成故障注入。提供多样化、可视化操作的故障注入自动化平台,作为各种演练和故障测试及验证的统一入口。通过故障注入平台能够帮助业务发现更多未知的影响业务稳定的问题,验证业务的告警有效性和完整性,以及业务的故障预案是否有效。作者比较推荐的是阿里巴巴开源的 ChaosBlade,ChaosBlade 内置的场景非常多,它不仅仅只能模拟 CPU 满载、磁盘 IO 过高等简单故障,还可以模拟 Dubbo 调用超时、杀容器、杀 pod 等,从而我们可以制造更多的实验场景,并且 ChaosBlade 方便易用,还可以自行扩展场景。
- 2 建立稳定性指标
既然故障演练就是混沌工程的一次实践,那么所有的演练都必然就要站在混沌工程“建立一个围绕稳定状态行为的假说”的原则基础之上开始设计,因此需要在开始之前定义好故障演练过程中需要监控的指标,这些指标可以正确地反映出系统的健康情况,并在出现问题的时候可以直接通过指标表现出来,也能知道对应的指标表现可能造成的结果,帮助触发监控预警,以便快速的解决问题。
- 3 定好故障类型
故障演练中触发的故障并不是随意选取的故障,而是通过对系统历史上出现的问题,以及类似系统出现过的问题的一次总结和归纳。常规用到比较多的故障有外部依赖超时访问,kafka 超时,kafka 不可用,数据可不可用,CPU 满载,网络中断,服务器宕机、磁盘没空间等。
- 4 流程准备
除去上面的一些故障相关准备以外,在开始故障演练前还要检查的流程准备是不是已经完善了,例如故障决策链是不是清晰明确,各种故障是否都有明确的故障排查和解决方案,每种方案是不是都确实可行。
- 5 开始演练
通知所有相关干系人,这里面包含了相关业务的开发工程师、业务工程师还有就是基础设施工程。通知内容包含参与故障演练的服务、故障演练的开始实践、故障演练的结束实践、故障演练对应服务的所在集群环境,建立统一协调的工作组即时聊天群。通过故障注入工具将问题注入到系统中,观察故障排查和解决的全过程,重点记录信息如下: - 故障有无按照预期被修复或者降低影响 - 业务指标的变化 - 稳定性指标变化 - 如果有降级处理,对应降级方案是否生效在故障演练过程中,如果出现任何超出控制或者超出原定计划的故障影响范围,都要马上终止故障演练,快速恢复系统,同时要清理全部故障演练对系统的影响和痕迹,因为故障演练实在真是环境中进行的,除去测试的业务之外,还有很多真实用户在使用系统,不能因为要完成故障演练而因此真是故障。
- 6 结束总结
重点中的重点是恢复故障演练的环节,故障演练都是在真实环境中完成的,因此一定要记住恢复全部环境,关闭故障注入工具,恢复降级处理的服务,以保证服务可以恢复到故障演练之前的正常状态。然后对过程做总结和,并且针对问题整改计划。
混沌工程的名字并不是说的混沌初开的意思,而是将系统搅乱,通过制造问题的方式提高系统稳定性。混沌工程出现还不算久,但是在很多大厂都在落地实践了,很多大厂都开源了自己的混沌工程的工具也公开了自己的故障演练的方案,但是故障演练是一件需要详细计划,有包含测试、研发、运维全部角色的推进小组落地完成的工作,某一个角色单打独斗是无法完成的。