Chaos Monkey

本文介绍了 Chaos Monkey

开发背景

2008 年 8 月, Netflix 主要数据库的故障导致了三天的停机, DVD 租赁业务中断,多个国家的大量用户受此影响。之后 Netflix 工程师着手寻找替代架构,并在 2011 年起,逐步将系统迁移到 AWS 上,运行基于微服务的新型分布式架构。这种架构消除了单点故障,但也引入了新的复杂性类型,需要更加可靠和容错的系统。为此, Netflix 工程师创建了 Chaos Monkey ,会随机终止在生产环境中运行的 EC2 实例。工程师可以快速了解他们正在构建的服务是否健壮,有足够的弹性,可以容忍计划外的故障。至此,混沌工程开始兴起。

Chaos Monkey 是在 Netflix 整体微服务化的形势下开发的。为了增加微服务架构的弹性,需要确保当服务集群中有节点失败或者退出时不会影响整体服务。由于 Netflix 的内部文化,没有办法通过框架或者编码规范来形成一套能够满足弹性要求的框架。最终,Netflix 选择开发了 Chaos Monkey:一个在生产环境随机选择并关闭服务的工具。通过频繁的服务失败演练,使得开发团队对服务集群稳定性有了更高的重视,以确保不会因为这些演练对最终用户产生影响。Netflix 将 Chaos Monkey 定位为提升服务质量的高效工具。

Spinnaker 是 Netflix 的持续交付平台,可以在 Spinnaker 上对 Chaos Monkey 进行配置。同时 Chaos Monkey 可以从 Spinnaker 获取服务部署的相关信息并通过 Spinnaker 关闭服务实例。由于集成了 Spinnaker,Chaos Monkey 增加了对多种后端的支持,包括:AWS、GCP、Azure、Kubernetes、Cloud Foundry。

技术原理

技术原理

使用场景(举例说明)

使用场景(举例说明)

模型

模型

Demo 搭建

Demo 搭建

使用方法

我们可以手动调用 Chaos Monkey 终止实例。 例如:

chaosmonkey terminate chaosguineapig test --cluster=chaosguineapig--region=**us**-east-1

应用中启用 Chaos Monkey,在 Spring Boot 应用中开启 Chaos Monkey 支持仅需要两步,首先在项目依赖中添加在 chaos-monkey-spring-boot。再然后,我们在应用启动时激活 chaos-monkey 的 profile。

<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>chaos-monkey-spring-boot</artifactId>
    <version>2.0.0-SNAPSHOT</version>
</dependency>
$java -jar target/order-service-1.0-SNAPSHOT.jar --spring.profiles.active=chaos-monkey

在 Codecentric Chaos Monkey 库的 2.0 版本中有个新的特性:Spring Boot Actuator 访问端口,通过 management.endpoint.chaosmonkey.enabled 属性来设置是否开启,在应用启动后,就可以通过 HTTP 访问端口来访问了。

设计场景与应用

设计场景与应用

补充内容

中断检查器

中断检查器用于在正在进行的中断期间自动禁用 Chaos Monkey。如果希望让 Chaos Monkey 检查是否有持续的中断并相应地禁用它,则需要:给你的中断检查人员起一个名字(例如,“聊天机器人”),在 Go 中编码一个实现中断接口的类型。修改outage.go,以便它识别你的中断检查器。编辑你的配置文件以指定中断检查器。

测试

运行这些测试的最简单方法是在本地计算机上安装 Docker。这些测试使用 mysql:5.6 容器(使用 5.6 版以确保与Amazon Aurora兼容)。

请注意,如果使用的是 macOS,则必须使用Docker for Mac而不是 Docker Toolbox。否则,将无法通过 127.0.0.1 访问 Docker 容器。

如果要运行这些测试,请确保已在本地安装 Docker,并抓住 mysql:5.6 容器:

docker pull mysql:5.6

然后使用 docker 标记运行测试,如下所示:

go test -tags docker ./...

测试将自动启动 mysql 容器,然后将其关闭。

如果在不上下移动 Docker 容器的情况下进行测试。如果你不希望测试每次都启动和关闭 mysql Docker 容器(例如,你想更快地运行测试,或者想通过本地运行 mysql 实例进行测试),请使用“dockerup”标志以及“docker”标志。

go test -tags "docker dockerup" ./...

启用组

如果 Spinnaker 将服务器组标记为启用,那么 Chaos Monkey 将仅考虑有资格终止的服务器组。Spinnaker API 公开了 isDisabled 布尔标志,以指示是否禁用了组。Chaos Monkey 对此进行了过滤,以确保它仅从活动组中终止。

可能性

对于每个应用程序,Chaos Monkey 将实例分为实例组(分组取决于应用程序的配置方式)。每个工作日,对于每个实例组,Chaos Monkey 都会掷一枚加权硬币,以决定是否从该组中终止实例。如果硬币朝上,Chaos Monkey 会安排在当天的上午 9 点至下午 3 点之间的任意时间终止。

在这种情况下,实例组终止之间的工作日数是一个具有几何分布的随机变量。

下面的等式描述了终止之间时间的概率分布。X是随机变量,n是终止之间的工作天数,p是硬币出现正面的概率。

$$P(X=n) = (1-p)^(n-1) × p, n>=1$$

X取期望得到平均值:

$$E[X] = 1/p$$

每个应用程序定义两个参数来控制 Chaos Monkey 应该为该应用程序实例执行的频率:

工作日之间的平均终止时间(μ),上班时间之间的最短间隔时间(ɛ),混沌猴子使用 μ 来确定 p 应该是多少。如果我们忽略 the 的影响并求解 p:

$$μ = E[X] = 1/p$$
$$p = 1/μ$$

例如,对于给定的应用程序,假定 μ= 5。在每一天,终止的可能性是 1/5。请注意,如果 ɛ> 1,混沌猴子的终止行为将不再是几何分布:

$$P(X=n) = (1-p)^(n-1) × p, n>=ɛ$$

特别是,随着 larger 变大,$E[X]-μ$ 也变大。我们不对此进行校正,因为数学上的额外复杂度不值得让 $E[X]$ 完全等于 $μ$。还要注意,如果 $μ=1$,则 $p=1$,这保证了每天终止。

追踪器

跟踪器用于记录某种外部系统中的终止事件。在 Netflix 内部,我们使用跟踪器记录到Atlas(我们的指标系统)和事件跟踪系统 1 Chronos 的终止 。

如果你希望记录某些外部系统的终止,则需要:给你的跟踪器起一个名字,在 Go 中编码一个实现Tracker界面的类型。修改github.com/netflix/chaosmonkey/tracker/getTracker,使其可以识别你的跟踪器。编辑你的配置文件以指定你的跟踪器。不幸的是,我们无法将这些跟踪器中的任何一个作为开源发布。我们的 Atlas 跟踪器与尚未发布为开源的Prana版本进行通信 ,Chronos 也尚未发布为开源。

供应商依赖性

如果要向 Chaos Monkey 添加新的依赖项,使用govendor进行添加。确保新依赖项的许可证与 Chaos Monkey 的许可证兼容:Apache License Version 2.0