NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

混沌工程实践经验:如何让系统在生产环境中稳定可靠

  • 2018-08-22
  • 本文字数:4458 字

    阅读完需:约 15 分钟

当你还是个孩子的时候,是否曾经为了了解某些东西的内部原理而故意把它们大卸八块?我们都这样做过。而在今天,我们把这种行为称为混沌工程。

作为开发者,我们的主要目标之一是开发稳定、安全且无错误的软件。为了实现这些目标,我们进行单元测试和集成测试,以便发现不可预期的行为,并确保我们测试的模式不会导致错误。现今的软件架构通常都包含了很多组件,单元和集成测试无法完全覆盖到这些组件。我们没注意到的一些服务器和组件在出现故障时仍然有可能将整个系统拖入深渊。

不是由你来选择那一刻,而是那一刻来选择你!

你只能选择为之做好准备。

——消防队长 Mike Burtch

背景简介

近年来,Netflix 一直是混沌工程背后的驱动者之一,极大地促进了混沌工程在分布式系统中的重要性。安全研究员 Kyle Kingsbury 采用了略微不同的方法,对分布式数据库、分布式队列和其他分布式系统的厂商所做出的承诺进行了验证。他使用 Jepsen 探测了上述系统的行为,得出了一些可怕的结论。你可以在 YouTube 上找到有关这个主题的演讲视频。

在本文中,我将对混沌工程做一个简单贴切的介绍。

不要低估了混沌工程社交性的一面,混沌工程不仅是关于如何摧毁某些东西,更重要的是把正确的人聚集在一起,共同创建稳定且容错的软件。

基础

我们在开发新的或已有的软件时,会通过各种形式的测试来增强实现。我们经常使用测试金字塔来表示应该要进行什么类型的测试以及做到怎样的程度。



测试金字塔说明了一种两难的境地:越是上层的测试,就会耗费越多的精力、时间和成本。

单元测试

我们通过单元测试来检验软件的预期行为。我们在没有依赖关系的情况下单独测试组件,并借助各种桩(mock)来控制它们的行为。这类测试不能保证它们是没有错误的。如果模块的开发人员在实现组件时犯了逻辑错误,那么这个错误也会在测试中出现——即使开发人员是先写的测试后写的代码。极限编程是解决这类问题的一种方式,在极限编程中开发人员在代码和测试之间不断交替。



集成测试

为了让开发人员和利益相关者能够与家人和朋友共度更多的空闲时间和轻松的周末,我们在编写完单元测试之后再编写集成测试。集成测试用于测试各个组件之间的交互。理想情况下,在成功运行单元测试并测试了相互依赖的组件之后,集成测试会自动运行。



得益于高测试覆盖率和自动化,我们的应用程序达到了非常稳定的状态,但在通往胜境的路上,相信每个人都体验过那种不愉快的感觉。我的意思是,我们的软件必须在生产环境中展示它真实的一面,看看它究竟有多好。只有在真实的条件下,我们才能看到每个组件的真实行为。而现代微服务架构的采用毫无疑问加重了这种不愉快的感觉。

软件架构的侵蚀

在松散耦合的微服务时代,软件架构可以使用“分布式系统”这个词来概括。各个系统都很好理解:它们可以进行快速的部署和扩展。但在大多数情况下,这会导致如下所示的架构:



我喜欢架构图,因为它们为我们提供了清晰而抽象的软件视图。然而,它们也可能将所有邪恶的陷阱和错误隐藏起来。它们特别擅长模糊底层和硬件。在现实生产环境中,以下架构图更接近现状:



因为防火墙规则的存在,负载均衡器不知道网关的所有实例或无法通过网络访问它们。有几个应用程序已经崩溃,但服务发现并未发现故障。此外,服务发现无法同步并提供不一样的结果。由于缺少服务实例,负载无法被分配,导致各个节点上的负载不断增加。为什么十二小时的批次作业必须在白天运行,而且为什么需要十二个小时?!

我相信你也有过类似的经历。你或许知道处理有缺陷的硬件、有问题的虚拟化、被错误配置的防火墙或进行公司内部繁琐的协调将意味着什么。

有时候,人们在讨论问题时会冒出这样的话:“这里没有出现混沌,一切都按照惯常的方式运作”。可能你很难相信,整个行业就是通过销售 ticket 系统而存活下来,这样我们就可以控制和记录混沌。下面的这句电影台词可以用来描述我们的日常生活:

混沌是驱动世界发展的引擎。

API 天堂 vs 后端地狱

API 试图要建立一个完美的世界,让我们通过调用定义好输入和输出的 API 获得我们需要的东西。我们使用了无数的 API,从而避免与地狱(后端或 API 实现)直接发生交互。我们实现了无数个抽象层,而冥王哈迪斯在这中间肆无忌惮地实施他的恶作剧。他的任务就是确保每一个 API 调用都受影响。好吧,我有点夸张了,但你们应该知道我想要说什么。

Netflix 展示了这将导致怎样的后果,所以让我们快速浏览一下它们的架构,以便更好地理解现代微服务架构的潜在复杂性。以下图片来自 2013 年纽约 QCon 大会的演讲:



更令人印象深刻的是,Netflix 的架构可以很好地运行,并对所有可能的错误做出反应。如果你观看 Netflix 开发人员的演讲,你会听到他们说“没有人知道它的工作原理,也没人知道为什么会这样”。这种洞见让混沌工程在 Netflix 生机勃勃。

不要随意尝试

在开始你的第一个混沌实验之前,请确保你的服务已经应用了弹性模式,并准备好处理可能出现的错误。

混沌工程不是制造问题,而是揭示问题。

——Nora Jones,Netflix 高级混沌工程师

正如 Netflix 的 Nora Jones 所指出的那样,混沌工程不是要制造混乱,而是要防止混乱。所以,如果你想要开始你的混沌实验,从小处开始,提前问自己以下问题:



如果你的基础设施——尤其是你的服务——没有为此做好准备,那么进行混沌实验是没有意义的。请记住这一点,现在我们现在开始进入混沌工程。

混沌工程规则

  1. 提前与你的同事讨论混沌实验计划!
  2. 如果你知道你的混沌实验将失败,请不要这样做!
  3. 混沌不应该让人感到意外,你的目的是证明假设。
  4. 混沌工程可帮助你更好地了解你的分布式系统。
  5. 控制混沌实验的影响范围。
  6. 在混沌实验期间控制好局面!

混沌工程原则

在混沌工程中,你应该完成下面描述的五个阶段,并始终控制好你的实验。从小处开始,并保持实验只有小范围的潜在影响。拔掉某处的插头,看看将要发生的哪些事情与混沌工程完全无关!我们不会制造不可控的混沌,反而要积极争取防止它们。

我强烈推荐 PrinciplesOfChaos.org 网站和免费电子书“Chaos Engineering(混沌工程)”。

混沌工程的阶段



稳定状态

最好先定义指标,让指标告诉你有关系统整体状态的可靠信息。在混沌实验期间,必须持续监控这些指标。当然,你也可以额外在实验之外监控这些指标。

指标可以是技术指标或业务指标——我认为业务指标比技术指标更重要。Netflix 在混沌实验期间监控用户成功播放视频的点击次数,这是他们的核心指标,属于业务领域。无法播放视频会直接到影响客户满意度。例如,如果你经营了一个在线商店,成功订单的数量或放置在购物篮中的商品数量将是重要的业务指标。

假设

事先想好应该发生什么情况,然后通过实验进行验证。如果你的假设无效,你必须根据调查结果找出错误,并将其提交给团队或公司。有时候,要做到完全不归咎责任是很困难的!作为一名混沌工程师,你的目标是了解系统的行为并向开发人员展示这些知识。这就是为什么要让每个人都尽早参到你的实验中。

现实世界中的事件

在现实生活中,有哪些问题正等待着我们?可能会发生什么样的新问题,哪些问题已经毁了我们之前的周末?在一个可控的实验中,我们必须先想清楚这些问题。

可能的例子包括:

  • Kafka 群集中的节点故障
  • 网络数据包丢失
  • 硬件错误
  • JVM 的 max-heap-size 参数设置不妥当
  • 延迟增加
  • 错误的响应

你可以随意往这个清单里添加其他的东西,只要始终与所选的架构紧密相关。即使你的应用程序不是由著名的云提供商托管,你自己公司的数据中心也会出现问题。我猜你一定能说出点东西来!

混沌实验示例

假设我们有几个通过 REST API 进行交互的微服务,并且使用了服务发现。为了以防万一,“产品服务”为“仓库服务”中的库存维护了一个本地缓存。如果仓库服务未在 500 毫秒内做出响应,则应使用缓存中的数据。我们可以在 Java 环境中实现这种行为,例如使用 Hystrix 或 resilience4j。因为有了这些库,我们可以非常轻松地实现回退和其他弹性模式。

环境



你将在下面找到一个成功的实验所需要的信息。

目标

仓库服务

实验类型

延迟

假设

由于调用仓库服务的延迟增加,因此 30%的请求使用了产品服务本地缓存中的数据。

影响范围

产品服务和仓库服务

之前的状态

OK

之后的状态

ERROR

结果

产品服务回退失败并导致异常,因为缓存无法对所有请求做出响应。

从结果中可以看出,我们使用了弹性模式,但仍然存在错误。必须通过再次运行实验来消除和测试这些错误。

自动化实验

混沌工程必须持续运行,你的系统也在不断变化:新版本进入生产环境、硬件更新、防火墙规则调整、服务器重新启动。最好的做法是在公司里建立混沌工程文化,并把它深植于每一位员工的心中。Netflix 通过让 Simian Army(Netflix 开源的测试套件工具,其中就包含了 Chaos Monkey)在生产环境中“肆意糟蹋”开发人员的产品来实现这一目标。虽然他们后来决定只在工作时间做这些事情,但总归有在做。

环境

对于第一次混沌实验,请选择与生产环境相同的环境。在风平浪静且与生产环境没有任何关联的测试环境中,你将无法获得任何有意义的结果。一旦你获得了初步结果并进行了改进,就可以继续进入生产环境,并在那里进行实验。混沌工程的目标是在生产环境中运行,并始终控制好局面,不要影响到用户。

开始混沌工程的第一步

起初,我很难在日常生活中理解和探索混沌工程的思想,毕竟我不是 Netflix、谷歌、Facebook 或优步的高级混沌工程师,况且我的客户才刚刚开始实施微服务。不过,我几乎总能找到 Spring Boot 的身影!有时是独立的应用,有时被部署在 Docker 容器中。我在技术大会上使用的演示总是至少包含一个 Spring Boot 应用程序。这导致了 Chaos Monkey for Spring Boot 的诞生,我们可以用它攻击现有的 Spring Boot 应用程序,而无需修改任何代码。

Chaos Monkey for Spring Boot

有关 Chaos Monkey for Spring Boot 将如何帮助你获得稳定的 Spring Boot 基础设施的所有相关信息,请访问 GitHub。

结论

我希望这篇文章能够帮助你理解混沌工程背后的理念和原则。混沌工程非常重要,即使我们不在 Netflix 工作,仍然有很多工作要做。我热爱我的工作,但更重要的是,我热爱与家人和朋友在一起的生活。我不想花费无数个夜晚和周末来修复严重故障,混沌工程让我们对我们的系统能够更好地应对生产环境中的恶劣条件充满了信心。

相关链接:

Jepsen: https://jepsen.io

Kyle Kingsbury 的演讲视频: https://www.youtube.com/watch?v=eSaFVX4izsQ

混沌工程电子书: https://www.oreilly.com/webops-perf/free/chaos-engineering.csp

Hystrix: https://github.com/Netflix/Hystrix

Resilience4j: https://github.com/resilience4j/resilience4j

Chaos Monkey for Spring Boot: https://codecentric.github.io/chaos-monkey-spring-boot

英文原文: https://blog.codecentric.de/en/2018/07/chaos-engineering/

感谢张婵对本文的审校。

2018-08-22 18:254014
用户头像

发布了 731 篇内容, 共 434.3 次阅读, 收获喜欢 1997 次。

关注

评论 1 条评论

发布
暂无评论
发现更多内容

跨平台应用开发进阶(五十一):HTML5(富文本内容)连续数字、字母不自动换行问题分析及解决

No Silver Bullet

html5 跨平台应用开发 三周年连更 问题分析及解决

一种面向后端的微服务低代码平台架构设计

京东科技开发者

架构 微服务 低代码 企业号 4 月 PK 榜

告别祈祷式编程|单元测试在项目里的正确落地姿势

浅羽技术

Java 测试 单元测试 JUnit 三周年连更

PDF编辑软件Acrobat Pro DC 2023 最新版+如何取消Acrobat更新教程

Rose

Acrobat Pro DC 2023 Acrobat Pro DC更新 如何取消Acrobat 自动更新

Java异常Exception详解

timerring

Java 三周年连更

通俗易懂篇:贝叶斯网络和它的应用

Bob

网络 贝叶斯算法

如何让 Windows 应用程序在 Parallels Desktop 中启动得更快

Rose

pd虚拟机 pd18虚拟机 Parallels Desktop启动

好家伙!阿里新产Java性能优化(终极版),涵盖性能优化所有操作

程序员小毕

数据库 性能优化 JVM 多线程 java面试

浅论分布式训练中的recompute机制

百度Geek说

机器学习 深度学习 分布式 企业号 4 月 PK 榜

Lambda 应用介绍及实现原理剖析

架构精进之路

Java 后端 Lamdba表达式 三周年连更

使用 Amazon SageMaker 构建文本摘要应用

亚马逊云科技 (Amazon Web Services)

基于树莓派设计的音视频播放器(从0开始)

DS小龙哥

三周年连更

中软国际亮相OpenHarmony开发者大会,荣获A类捐赠人授牌认可

科技热闻

PicConvert for mac:以批处理模式转换,调整大小和重命名图像

Rose

苹果软件资源 图片格式转换 PicConvert mac mac图片编辑

企业微信接入系列-扫码绑定/登录

六月的雨在InfoQ

企业微信 三周年连更 企业微信扫码 企业微信接入

一文读懂物联网 MQTT 协议之基础特性篇

老周聊架构

三周年连更

基于UDP协议的Socket通信

智趣匠

UDP协议 客户端配置 三周年连更

SpringBoot如何使用Jetty容器?超级详细,建议收藏

bug菌

springboot jetty 三周年连更

vue3学习-Composition API

格斗家不爱在外太空沉思

Vue 3 三周年连更

从多个数据源中提取数据进行ETL处理并导入数据仓库

海拥(haiyong.site)

三周年连更

图计算引擎分析--GridGraph

京东科技开发者

系统 磁盘 图计算引擎 企业号 4 月 PK 榜 GridGraph

Shell在日常工作中的应用实践

京东科技开发者

Linux Shell 服务器 shell脚本编程 企业号 4 月 PK 榜

Unity 之 查找游戏物体的几种方式汇总解析

陈言必行

Unity 三周年连更

强大易用的矢量图形设计工具Sketch v96.1最新中文版

Rose

苹果软件下载 Sketch中文版 Sketch V96.1 mac图形设计工具

2023年超全前端面试题-背完稳稳拿offer(欢迎补充)

肥晨

三周年连更

Django笔记十一之外键查询优化select_related和prefetch_related

Hunter熊

Python django 外键查询优化 select_related prefetch_related

逐渐消失的站长圈子,未来个人站长如何转型

石头IT视角

基于Flutter实现跨平台离线大模型对话应用

轻口味

flutter ios android AI 三周年连更

Docker容器网络的七种武器

王玉川

Docker 容器 网络 VXLAN 网络虚拟化

近期Master分支代码编译异常的解决方案

坚果

OpenHarmony OpenHarmony3.2 三周年连更

Mac音频采样器Kontakt 7最新版v7.3.0下载

Rose

mac音频采样器 Kontakt 7激活版 Native Instruments Kontakt 7 mac下载

混沌工程实践经验:如何让系统在生产环境中稳定可靠_语言 & 开发_Benjamin Wilms_InfoQ精选文章