这是一篇较为详细的混沌工程调研报告,包含了背景,现状,京东混沌工程实践,希望帮助大家更好的了解到混沌工程技术,通过混沌工程实验,更好的为系统保驾护航。
Netflix 公司最早系统化地提出了混沌工程的概念。2008 年 8 月,Netflix 公司由于数据库发生故障,导致了三天时间的停机,使得 DVD 在线租赁业务中断,造成了巨大的经济损失。于是 Netflix 公司开始尝试利用混沌工程优化稳定性保障体系。2010 年,Netflix 公司开发了混沌工程程序 Chaos Monkey,于 2012 年在 Simain Army 项目中开源,该程序的主要功能是随机终止在生产环境中运行的虚拟机实例和容器,模拟系统基础设施遭到破坏的场景,从而检验系统服务的健壮性。2019 年,阿里巴巴开源了 ChaosBlade 混沌工程程序,该程序可以结合阿里云进行混沌工程实验。2020 年,PingCap 作为国内优秀的数据库领域开源公司,开源了其公司内部的混沌工程实践平台 ChaosMesh。
基于以上开源项目,混沌工程项目在国内受到了多家公司的关注,越来越多的公司开始引入混沌工程进行系统稳定性保障工作,通过混沌工程主动注入故障的方式,避免软件系统带来的未知危机。图 1.1 展示了软件系统稳定性危机与对策发展时间线的对应关系,可以发现,随着软件系统规模的扩大,系统复杂度的增长及开发周期缩短,陆续爆发了多次软件危机,同时,每次的软件危机都促进了软件系统稳定性保障措施的不断完善。而当下的软件系统的规模,复杂度和开发敏捷程度再次迈入了一个新的阶段,导致系统的稳定性面临着新的挑战。此时,主动发现系统稳定性缺陷的混沌工程应运而生,再次弥补了当下系统稳定性保障方式的短板。
图 1.1 软件系统稳定性危机和对策发展时间线图 [来源:中国信息通信研究院]
塔勒布曾经在《反脆弱》一书中阐述了 “系统如何在不确定性中获益” 的思想,混沌工程基于这一伟大思想,提倡使用一系列实验来真实地验证系统在各类故障场景下的表现,通过频繁地进行大量实验,使得系统本身的反脆弱性持续增强。每一次故障中的获益,让系统不断进化,形成正向循环,逐步提高系统的质量,保证系统的健壮性。因此,混沌工程研究的首要目的就是主动发现系统的稳定性缺陷。表 1-1 列举了近几年比较严重的几个系统稳定性故障事件,从侧面反映了系统稳定性保障的重要性。
表 1-1 系统稳定性故障事件
公司名称 | 发生时间 | 持续时长 | 影响范围 | 故障原因 |
---|---|---|---|---|
哔哩哔哩 | 2021 年 7 月 | 约 1 小时 | 影响了视频播放、直播等多个核心服务 | 机房故障,灾备系统失效 |
滴滴 | 2021 年 2 月 | 约 1 小时 | 滴滴打车 APP | 系统内部错误 |
谷歌 | 2020 年 12 月 | 约 1 小时 | 谷歌旗下多个业务 | 存储超出限额 |
亚马逊 | 2020 年 11 月 | 约 5 小时 | 部分服务器无法访问 | 不当的运维操作触发了系统漏洞 |
微软 | 2020 年 9 月 | 约 5 小时 | Microsoft Office 36 办公软件和 Azure 云产品 | 流量激增导致服务中断 |
当混沌工程成为常态化的系统稳定性的保障手段后,系统的整体稳定性将得到进一步提升。通过混沌工程平台,主动向系统注入故障,验证和评估系统抵抗故障并保持正常运行的能力,提前识别未知的缺陷并进行修复,保障系统更好得抵御生产环境中的失控条件,有效提升系统的整体稳定性。
混沌工程的主要研究意义在于提高系统的稳定性,通过主动向系统中注入故障的方式,研究和提高系统的健壮性,在一定程度上弥补了系统发生故障时被动响应的短板,降低了系统应对故障的风险和成本。表 1-2 列举了使用混沌工程前后的系统稳定性保障方式的对比,可以发现,使用混沌工程后,系统稳定性的保障方式更加出色。
表 1-2 使用混沌工程前后的系统稳定性保障方式对比
对比内容 | 使用混沌工程前 | 使用混沌工程后 |
---|---|---|
发现缺陷的方式 | 线上缺陷发生时才开始识别 | 主动注入故障发现系统缺陷 |
应对缺陷的方式 | 被动响应,缺陷应对的开始时间取决于故障何时发生 | 主动响应,缺陷应对的开始时间取决于混沌工程的实验时间 |
识别缺陷的效率 | 较低,对于触发条件苛刻的潜在缺陷可能需要很长时间 | 较高,通过主动注入故障,使得潜在缺陷尽快暴露 |
响应缺陷的成本 | 可控性较差 | 可控性良好 |
另外,实践混沌工程对不同职位的工作人员也有着各自的意义。如表 1-3 所示,混沌工程有助于帮助系统相关人员发现潜在的脆弱点,降低系统稳定性缺陷可能造成的损失。同时,通过混沌工程注入故障,可以有效锻炼团队发现和定位问题并快速恢复系统的能力。
表 1-3 实践混沌工程对不同职位的意义
职位 | 实践混沌工程的意义 |
---|---|
软件开发工程师 | 进一步加深对系统的理解,验证系统架构的容错能力 |
测试开发工程师 | 弥补传统测试方法留下的空白,更主动的方式发现系统的问题 |
运维开发工程师 | 提高系统故障的应急效率,实现故障告警、定位、恢复的有效应对 |
产品经理 | 了解产品在突发情况下的表现,提升客户在突发情况下的产品使用体验 |
图 1.2 混沌工程实践体系和软件开发一般流程联系图 [来源:中国信息通信研究院]
根据调研的混沌工程实践经验,混沌工程的研发方法可以概括为图 1.2 中的混沌工程实践体系。其中,混沌工程实践配套是混沌工程成功实践的关键,因此要求实践团队做好混沌工程实践的战略规划,培养混沌工程实践相关人员,形成混沌工程文化,识别应对潜在的风险并对混沌工程实践做出有效的评估。在此基础上,混沌工程实验是混沌工程研究的核心工作,即混沌工程以实验为最小单元研究发现系统的稳定性缺陷,实验的一般流程是:实验设计、实验实施和结果分析。具体内容一般包括:实验需求和对象、实验可行性评估、观测指标设计、实验场景环境设计、实验工具平台框架选择、实验计划和沟通、实验执行及指标收集、环境清理与恢复、实验结果分析、问题追踪、自动化持续进行验证。当通过混沌工程发现了系统稳定性缺陷时,需要根据实际情况给出对应的解决方案,如果存在架构的缺陷,则需针对性得采用韧性设计对稳定性缺陷进行改进,其他如边界条件和极端情况未考虑或者编码错误的缺陷,若占比较高且反复出现,则需要评估是否需要在制度规范上对软件开发过程进行更好的管控。
关于更加具体理的论和混沌工程的一般实验步骤,可以从该书《混沌工程:Netflix 系统稳定性之道》中获取到,电子版书籍见本报告附录。该书对混沌工程进行了非常详细的阐述,图 1.3 为该书的目录结构。
图 1.3《混沌工程:Netflix 系统稳定性之道》目录
目前业界使用的混沌工程工具的种类很多,表 2-1 汇总了本次调研中发现的业内保持维护更新的几个工具,不同工具侧重于不同种类的故障注入。
表 2-1 混沌工程工具汇总
工具名称 | 最新版本 | 核心语言 | 包含场景 | 特定依赖 |
---|---|---|---|---|
ChaosBlade | 1.7.0 | Go | 实验框架,支持系统资源、网络、应用层面等多种故障的注入 | 无特定依赖 |
ChaosMesh | 2.3.1 | Go | 实验框架,支持系统资源、网络、应用层面等多种故障的注入 | 依赖于 K8s 集群 |
ChaosToolkit | 1.12.0 | Python | 实验框架,可集成多个 IaaS 或 PaaS 平 台,可使用多个故障注入工具定制场景, 可与多个监控平台合作观测和记录指标信息 | 通过插件形式支持多个 IaaS、PaaS,包括 AWS/Azure/Goog le/K8s |
orchestrator | 3.2.6 | Go | 纯 MySQL 集群故障场景 | 无特定依赖 |
powerfulseal | 3.3.0 | Python | 终止 K8s、Pods,终止容器,终止虚拟机 | 支持 OpenStack/AWS/ 本地机器 |
toxiproxy | 2.5.0 | Go | 网络代理故障,网络故障 | 无特定依赖 |
业内的混沌工程平台一般由:用户界面、任务调度模块、故障注入、监控告警系统四个部分组成。
用户界面: 为实验平台提供混沌工程实验任务的编排和配置服务,使得用户方便管理各类混沌工程实验任务。当混沌工程实验开始后,用户可以通过任务进度条、服务器指标等展示图实时的查看实验进度和系统指标情况。当混沌工程实验结束后,用户可以看到最后的混沌工程实验报告。
任务调度模块: 该模块负责用户界面和故障注入之间的交互,核心功能是实现混沌工程任务的批量下发和调度。
故障注入: 故障注入负责接收任务调度模块下发的故障注入任务,实现相应的故障注入事件,并反馈故障注入任务的执行状态。
监控告警系统: 该系统负责记录和管理系统产生的所有数据,生成告警和相关统计并反馈给用户。
混沌工程实践能力的评估可以帮助团队更好地了解混沌工程实践的状况,表 2-2 列举了混沌工程实验成熟度的等级,该等级可以用来评估当前系统进行混沌工程实践的能力,主要反映执行混沌工程实践的可行性、有效性和安全性,等级越高则说明可实践混沌工程的能力越强。
表 2-2 混沌工程实验成熟度等级
泰山混沌工程平台是基于业界成熟解决方案 ChaosBlade 并结合京东业务特色设计并落地实现的一款自助式故障演练平台。用户可根据自身服务特点有针对性的场景编排、故障注入,对服务容灾能力进行评估,通过实验探究的方式建立对系统行为重新的认知理解。推动建立混沌文化,通过主动探索的方式发现系统中潜在的、可以导致灾难的、让我们的客户受损的脆弱环节,消灭它们,让我们的系统更加健壮有韧性。
图 3.1 展示了泰山混沌工程演练的流程图,基于泰山混沌平台,红方的任务是:
(1)创建演练计划:通过访问泰山平台,进入路径:安全生产 - 混沌工程页面,页面提供 “创建演练计划” 按钮,点击即可进入演练配置页面。
(2)演练配置:点击创建演练计划按钮后,进入演练配置页面,可录入演练基本信息及任务配置项(演练配置 - 应用相关(类型、方式、场景)、演练配置 - 执行相关),图 3.1 中红色字体为本次演练重点配置项。
(3)执行演练:演练任务创建保存后,生成一条待执行的演练任务,手工点击执行按钮执行演练。
蓝方的任务是:
(1)故障排查:在演练执行中,蓝方通过报警信息,先下掉报警机器,进行排查。
(2)恢复方案:演练中发现问题要及时恢复,演练后要重启恢复演练机器,确保机器正常运行
实验完成后需要进行演练复盘,即对演练中发现问题总结及分析,确保不再出现类似风险问题。
图 3.1 泰山混沌工程演练流程图【来源:全渠道混沌工程实践文章】
平台的核心能力可以用四化一灵活概括,即:
一、自动化:演练过程全程自动调度、插件部署、故障注入、现场恢复。
二、可视化:演练期间,可实时观测 MDC 指标变化、UMP 业务监控指标变化以及故障注入进度等。
三、精准化:可通过指定 IP、分组、机房、网络 POD,针对演练影响范围进行明确限制,演练效果更贴合实际场景。
四、规模化:平台设计目标支持单任务 1000+ 演练目标、多演练任务同时调度的能力,为集团范围内各种预案演练、攻防演练、常态化混沌测试提供强有力的支持。
五、灵活控制:在演练过程中可灵活进行取消、终止、全部终止等操作;针对故障场景可多维度进行配置提调整;演练时长、调度方式执行时可调整。
泰山混沌工程实验平台支持丰富的混沌场景能力,表 3-1 列举了平台支持的基础资源类故障场景,主要验证基础资源或者业务监控告警的及时性、有效性(干预手段),从而优化资源规格、部署规模和跨机房部署,同时希望增加进程存活、URL 存活的监控。表 3-2 列举了平台支持的 JAVA 进程故障和中间件依赖故障场景,主要验证业务、JVM 监控告警的及时性、有效性(干预手段),从而调整 JVM 参数、使用合理垃圾回收器等,同时调整中间件集群配置、治理降级方案、优化缓存策略等,通过演练也可以进一步理解系统架构,梳理强弱依赖、治理服务性能和评估下游服务能力。
表 3-1 基础资源类故障场景
混沌场景 | 演练目的 | 实现原理 |
---|---|---|
CPU 高负载 | 关注对业务处理吞吐率的影响 | 消耗 CPU 时间片 |
内存占用 | - | 采用代码申请内存实现 |
磁盘 IO 高负载 | 评估对磁盘读写敏感的业务的影响 | 使用 dd 命令实现 |
磁盘填充 | 主要验证如日志目录打满对服务的影响 | 使用 fallocate、dd 命令实现 |
网络延迟 | 评估业务对网络延迟的容忍程度,评估超时、重试机制设置是否合理,防止级联事故 | 使用 tc 命令实现 |
网络丢包 | 评估业务对网络丢包的容忍程度 | 使用 tc 命令实现 |
进程假死 | 观测负载均衡时效性、业务敏感性 | kill -STOP {pids} |
进程终止 | 观测负载均衡时效性、业务敏感性(Nginx&Tomcat) | kill -9 {pids} |
表 3-2 JAVA 进程故障和中间件依赖故障场景
类型 | 混沌场景 | 演练目的 |
---|---|---|
JAVA 进程故障 | 进程 CPU 满载 | 评估服务节点 CPU 满载时对服务的影响 |
内存溢出 | 评估 GC 对服务的影响 | |
接口延迟 | 评估接口故障对整体 SLA 的影响 | |
接口抛异常 | 评估接口故障对整体 SLA 的影响 | |
接口返回值篡改 | 评估针对非预期接口返回的处理 | |
线程池打满 | 评估线程池打满对服务的影响 | |
中间件依赖故障 | JSF 请求延迟 | 评估中间件故障对自身的影响 |
JSF 请求抛异常 | 评估中间件故障对自身的影响 | |
JIMDB 请求延迟 | 评估中间件故障对自身的影响 | |
JIMDB 请求抛异常 | 评估中间件故障对自身的影响 | |
MYSQL 请求延迟 | 评估中间件故障对自身的影响 | |
MYSQL 请求抛异常 | 评估中间件故障对自身的影响 |
表 3-3 汇总了泰山混沌实验平台的故障使用统计表,从使用情况上可以看出,目前基础资源类故障场景使用居多。图 3.2 更加直观的展示出泰山混沌工程实践平台的故障使用类型为基础资源类故障。
表 3-3 泰山混沌工程实验平台故障类型使用统计表
故障类型 | 演练占比 |
---|---|
网络故障 | 31% |
内存耗尽 | 13% |
CPU 打满 | 23% |
磁盘故障 | 9% |
进程异常 | 3.5% |
Java 进程故障 | 6.5% |
外部依赖故障 | 14% |
通过调研泰山混沌工程的实践,可以汇总一些常见问题如下:
(1)报警未配置(MDC、UMP、存活);
(2)报警阈值不合理、间隔时长不合理、联系人缺失、联系人授权不足;
(3)进程假死未报警,需配置 URL 存活报警;
(4)暂停了告警,未及时开启;
(5)值班人员对预案处理不熟练,内部系统工具使用不熟练(加强内部培训);
(6)群组内反馈问题后,未有相关同事进行处理,职责分工不明确;
(7)内部工具设计不合理,无法应对不同场景(比如:多机房分组出异常);
(8)忽视偶发问题,后期范围扩大不易处理(比如:低版本 Linux 内核处理)。
本次调研涵盖了混沌工程的起源,发展,以及在京东的落地情况。通过研究,我进一步体会到:(1)混沌工程最先进的,是它大胆超前的思维理念和安全受控的方法论。(2)故障注入只是手段,而不是混沌工程的全部。场景再多,也不代表韧性就够好。(3)如果只是根据稳态假说,写测试用例,然后再使用故障注入工具进行试验,最后结果验证,这只能算是混沌工程最基本的内容。(4)混沌工程的使命是探索问题,而不仅仅是验证问题。总体而言,混沌工程的核心就是增强系统信心,保证系统在某个场景下的能力不退化。
混沌工程的目标是主动发现问题,因此,未来依然离不开这个核心目标,但是在未来,可以使得这个目标更加智能化的实现。通过调研发现,业界中部分企业已经开始探索将混沌工程和人工智能、机器学习等领域相结合,通过注入故障时系统指标的变化和定位的历史数据进行相关模型的训练,使得模型可以通过指标变化自动识别故障,这将有助于解决混沌工程在结果分析和故障恢复环节的自动化问题。其次,当下的混沌工程演练平台的交互性和可视化等能力在未来可以做到更好。此外,混沌工程的量化指标也需要进一步完善。
1.ChaosMesh https://github.com/chaos-mesh/chaos-mesh
2.ChaosBlade https://github.com/chaosblade-io/chaosblade
3.ChaosToolkit https://github.com/chaostoolkit/chaostoolkit
4.orchestrator https://github.com/openark/orchestrator
5.powerfulseal https://github.com/powerfulseal/powerfulseal
6.toxiproxy https://github.com/Shopify/toxiproxy
7.混沌工程深度实战专场 https://live.juejin.cn/4354/xdc2021-01
作者:京东零售 贾安
来源:京东云开发者社区