混沌工程:通过可控故障实验提升软件系统可靠性
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.5 初识混沌工程

在一切变得技术化之前,让我们闭上眼睛,快速绕道前往虚构的北欧岛国格兰登(Glanden)。格兰登人的生活是愉快的。地理位置为其勤奋的人们提供了温和的气候和繁荣的经济。格兰登的中心是其首都多伦(Donlon),有约800万人口,有着来自世界各地丰富的历史遗产——这是一个真正的文化大熔炉。在多伦,我们虚构的初创公司FizzBuzzAAS(FizzBuzz-as-a-Service,FizzBuzz即服务)正努力使世界变得更美好。

1.5.1 FizzBuzz即服务

FizzBuzzAAS公司是多伦蓬勃发展的科技领域中的一个后起之秀。它成立于一年前,已经在FizzBuzz即服务市场上确立了明显的领导地位。最近,在获得巨额风险资本(VC)资金支持的情况下,该公司正在寻求扩大其市场范围并扩大其业务规模。以FizzBuzzEnterpriseEdition(https://github.com/EnterpriseQualityCoding/FizzBuzz EnterpriseEdition)为例的竞争是激烈而无情的。FizzBuzzAAS业务模型非常简单:客户每月支付固定的订阅费即可访问最先进的API。

Betty是FizzBuzzAAS的销售主管,她天生就是这块料。她即将签订一份大合同,这可能会决定这家雄心勃勃的初创公司的成败。几个星期以来,每个人都在饮水机旁谈论这份合同。空气中弥漫着紧张的气息。

突然,电话响了,所有人都变得安静下来。这是大公司的电话。Betty接了,“嗯……是的。我明白。”当时是如此的安静,你可以听到外面的鸟鸣声,“是的女士。是的,我会给你回电。谢谢。”

Betty站起来,意识到每个人都屏住了呼吸,“我们最大的客户无法访问API。”

1.5.2 漫漫长夜

这是公司历史上第一次让整个工程团队(Alice和Bob)通宵达旦工作。最初,没有发现任何问题。他们可以成功地连接到每个服务器,服务器报告运行状况良好,并且预期的进程正在运行并做出响应——那么错误是从哪里来的呢?

更重要的是,他们的架构并没有那么复杂。外部请求将到达负载均衡器,负载均衡器将路由到API服务器的两个实例之一,API服务器将查询缓存并提供预计算的响应(如果它足够新的话),或者计算一个新的响应并存储在缓存中。你可以在图1.3中看到这个简单的架构。

终于,在深夜喝了大量咖啡后,Alice找到了第一块拼图。“这有点奇怪,”她在浏览一个API服务器实例的日志时说,“我没有看到任何错误,但所有这些请求似乎都在查找缓存时停止了。”Wow!不久之后,她发现了问题:代码优雅地处理了缓存中断(拒绝连接,没有主机,等等),但在没有响应的情况下没有任何超时。从这开始事情有了进展——快速进行结对编程,快速构建和部署,是时候小睡了。

世界秩序恢复了。人们可以继续发请求给FizzBuzz即服务,风投的钱也花得很值。这家大公司认可了这个问题修复,甚至没有提及取消合同。太阳又出来了。后来,事实证明API服务器无法连接到缓存是由一个糟糕的防火墙策略导致的,在该策略中,有人忘记将缓存列入白名单。这是人为的错误。

图1.3 FizzBuzz即服务技术架构图

1.5.3 后续

“我们如何确保下次不会再发生这种情况?”Alice问道。这次会议对公司的未来至关重要。

鸦雀无声。

“好吧,我想我们可以偶尔先发制人地让一些服务器着火。”Bob回答说,以此来提振气氛。

每个人都笑了。每个人,除了Alice。

“Bob,你真是个天才!”Alice欢呼道,然后花了一会儿时间欣赏大家瞪大的眼球,“我们就这么做吧!如果我们能够像这样模拟一个不完善的防火墙规则,那么我们就可以把它添加到我们的集成测试中。”

“你是对的!”Bob从椅子上跳了起来,“这很容易!为了在家里的路由器上屏蔽我孩子的《反恐精英》服务器,我经常这么做!你需要做的就是这样。”他说着,开始在白板上写:

“然后在测试结束后,我们可以用这个来撤销它。”他继续说道,他感到同事们对他的尊敬与日俱增:

Alice和Bob将这些修复作为集成测试的开始和退出时的一部分来实现,然后确认旧版本不能工作,但是包含修复的新版本工作得很好。同一天晚上,Alice和Bob都在LinkedIn上把自己的职位头衔改成了网站可靠性工程师(Site Reliability Engineer,SRE),并达成协议,永远不会告诉任何人他们在生产过程中修复了这个问题。

1.5.4 混沌工程简述

如果你曾经在一家初创公司工作过,像这样喝着咖啡度过漫漫长夜对你来说可能并不陌生。能理解的请举手!虽然很简单,但这个场景展示了前面介绍的所有四个步骤的作用:

可观测性指标是我们是否能成功调用API。

稳态是API成功响应。

假设是如果我们断开对缓存的连接,仍能成功获得响应。

运行实验后,我们可以确认旧版本存在故障,新版本可以正常工作。

干得好,伙计们!你们刚刚增强了系统在困难条件下生存的信心!在这个场景中,团队是被动的:Alice和Bob想出这个新测试只是为了应对他们的用户已经注意到的一个错误。这使得情节产生了更戏剧性的效果。在现实生活中,在本书中,我们将尽最大努力预测并主动检测此类问题,而无须在一夜之间失业的外部刺激!我保证在这个过程中我们会获得一些真正的乐趣(请参阅附录D)。