首先混沌工程目的是帮助我们对系统整体质量有所了解,即对该系统在生产环境中是否能够应对各种威胁和故障的预判,从而建立信心。目前混沌工程实验大多用来测试系统弹性对抗方面的验证,而这些实验基本都来自以下3个方面:基础设施故障、网络故障、应用程序故障。
混沌工程中的场景可以划分为故障和非故障两类。
- 故障类场景涵盖系统中的服务发生故障或者利用工具向系统中注入相应的故障,如超时、异常错误等。如何将故障注入这类服务架构中呢?最简单的方法是将实例通过混沌工程实验进行异常关闭,当然也可以将磁盘卷进行异常卸载,或容器异常关闭,或将RDS数据库实例进行故障切换等。当然我们也可以将某段错误代码注入服务中。这些故障场景我们已经了解到,其会对系统产生哪些影响,我们同时期望系统能够正确响应我们设置在系统中的应对方案。
- 非故障类场景,当系统突然面临大量请求时,如“双十一”整点秒杀或支付时,系统的负载均衡机制能否正常分流请求,触发我们之前设置的负载均衡策略,例如我们采取服务熔断机制,防止整个系统出现雪崩,或者暂时停止对该服务的调用和采用降级处理等策略,暂时舍弃系统的一些非核心接口和数据请求,直接返回一个提前准备好的回退(fallback)错误处理信息。这样,虽然我们提供的是一个不完整的服务,但保证了整个系统的稳定性和可用性。
其他类似非故障类场景还有系统资源竞争、拜占庭将军故障(例如系统中性能差或有异常的节点对请求做出错误的响应、发生异常行为、对调用者随机返回不同的响应等)、非计划中的或非正常组合的消息处理等。系统在面对这些异常时,处理方式往往是未知的,故需要进行相应的实验探究。
再谈到微服务,现阶段早已成为团队开发和部署首选的设计模式。微服务让开发人员可以使用更集中、更轻量化的代码库,并且能够独立决定何时以及如何部署服务。然而,天下没有免费的午餐。当你从单体架构过渡到微服务架构时,复杂性并没有随之消失,反而随着微服务数量的增多而增加。
在使用微服务构建的系统时,会有更多的主机或容器、更多的负载均衡器、更多的防火墙规则等在运行。我们可能将Nginx用于不同的业务场景(Web服务、反向代理、负载均衡等),以满足不同的微服务需求。随着服务数量从几十个增长到几百个甚至上万个,我们想要理解系统与预测其行为就变得更加困难。此外,所有业务都通过网络相互协作,而不是通过系统内部的模块调用,这样性能也随之成为微服务面临的主要问题之一。
同时,随着微服务架构和容器编排技术K8S的盛行,增加了评估此类系统可靠性的难度。要解决微服务带来的运维工作量的增加、复杂链路的监控难题,以及服务间性能开销等问题,需要我们基于分布式的微服务架构进行混沌工程实验,测试有关分布式服务体系结构的假设以及验证上面所提及的问题,并发现分布式服务体系结构中存在的未知行为,例如,当集群中某个节点的CPU负载达到峰值、系统发生错误时,实验中的微服务系统将会表现出的行为。最终我们的目标是验证微服务系统在不利条件下的运行情况是否达到预期,并了解可采取哪些措施使系统具有更大的弹性来适应这些变化。
混沌工程最终目标是帮助我们的团队更好地管理生产环境中运行的应用,并使系统更具弹性。