作者 | 去哪儿网基础平台团队
前言
微服务架构已经在去哪儿网(Qunar)实施多年,微服务应用数量达到数千之多,随着服务之间的调用链路越来越复杂,故障频频发生,给公司带来巨大的经济损失,稳定性建设工作就成为了一项重要的工作。从 2010 年 Netflix 提出通过 Chaos Engineering 的方式提升系统稳定性之后,到今天 Chaos Engineering 已经被证明是一种有效的发现系统弱点,建立对系统抵御生产环境中失控条件的能力以及信心的有效手段。从 2019 年底去哪儿网也结合自身的技术体系开始进行混沌工程相关的探索,下面就来介绍下我们的实践经验。
选型
为了避免重复造轮子,我们在启动项目之初调研了当时已经开源的混沌工程相关工具,并结合自身的技术体系特点进行了分析:
- 当时基础资源以 KVM 为主,同时也在探索容器化,所以两个平台都需要支持。
- 公司内部主要的技术栈为 Java。
基于上面的两点,加上社区活跃情况等,选择 ChaosBlade 为故障注入的工具,加上自研的混沌工程控制台(当时还没有 chaosblade-box)作为最终方案。
架构
基于公司内部的系统体系,整体的架构如下:
纵向来看,自上而下:
- 服务治理,Portal(提供应用画像,CICD的平台)提供了应用的依赖关系,应用的属性,运行时资源等信息,通过混沌工程UI可以创建出故障演练(故障演练包含了应用信息,应用资源,待注入故障等);
- 混沌工程控制台(Chaos控制台),提供了多个应用多个故障的任务流程编排,故障演练流程的控制的功能;
- Saltstack,chaosblade-operator 提供了 chaosblade 的安装和卸载能力;
- 应用的资源分为 KVM 和 K8S 承载的容器,故障演练编排系统通过 Restful API 和 chaosblade 启动的 HTTP 服务进行通信,来进行故障的注入和恢复。
横向来看:
- 自动化测试平台主要提供演练时线上 case 的回归能力,以及用来做强弱依赖的标记断言;
- 演练开始时,Chaos控制台会监听相关应用的核心指标告警,如果有告警信息会通知给相关负责人并终止和恢复演练,这样可以及时止损。
系统演进
去哪儿网这边的混沌工程主要经历了 2 个阶段:
1、故障注入能力的建设。这个阶段主要解决的问题是用户可以手动的通过创建故障演练,通过合适的故障策略来验证系统的某些方面是否符合预期;
2、提供强弱依赖场景下的,依赖标记,强弱依赖验证,以及自动化强弱依赖闭环的能力,用混沌工程来提高微服务治理效率。
4.1 故障演练
通过故障注入来模拟故障发生是混沌工程的基础能力。在这个阶段主要提供 3 种场景的故障注入,机器关机,OS 层的故障,以及 Java 应用的故障注入,在此基础之上我们还做了场景化的功能。
4.1.1 演练流程
一个典型的演练流程如下:
4.1.2 难点
- 开源故障策略不足
chaosblade-exec-jvm 中提供了 Java 故障注入的基础能力,也提供了部分开源组件的插件,但是对于公司内部的组件来说还是不足。于是我们中间件的同学进行了二次开发,增加了 AsyncHttpClient, QRedis 故障注入相关的插件,同时也针对 HTTP DUBBO 增加了基于调用点的故障注入功能。
- 容器化改造
2021年中,去哪儿网开始应用的容器化迁移,故障演练也需要支持容器化下的演练。基于 chaosblade-operator 做了如下几个方案选型:
方案 |
说明 |
优势 |
劣势 |
chaosblade-operator |
完全采用开源方案,Agent安装和策略注入都使用CRD的方式 |
贴近云原生,CRD比较完善 |
控制端需要重新开发一套对接K8s的故障注入流程,前端给用户的策略也需要重新兼容,如果新增策略也需要开发CRD |
sidecar |
伴随应用整个应用周期,也需要通过CRD或者exec的方式来操作agent |
提前占用内存,CPU资源,只解决了agent安装问题,策略下发和控制端逻辑没解决 |
|
chaosblade-operator + blade server |
使用CRD完成Agent的安装卸载,策略注入还是使用http端口交互的模式 |
改造成本小,控制端跟KVM的方式一致 |
需要对 chaosblade-operator 进行部分功能的二次开发 |
方案中主要关注的3个问题:
- agent的安装和卸载
- 策略的注入和恢复
- 控制端的改造成本
基于上面几个方案的对比,最终是基于方案 3 进行实施的。
4.2 强弱依赖自动闭环
4.2.1 背景
基于故障演练平台我们提供了强弱依赖场景下的故障演练功能:
- 应用间依赖信息展示,依赖关系标注
- 根据依赖信息,反填故障策略参数
但是整个强弱依赖关系的验证还是需要人来驱动,于是我们结合了自动化测试工具开发强弱依赖自动标记的功能,通过自动化的流程完成强弱依赖关系的维护,形成闭环。
4.2.2 方案
chaos 控制台会周期性的从服务治理平台获取应用的依赖关系,根据下游接口来生成基于抛异常策略的故障演练。接着对应用的测试环境进行故障注入,再通过自动化测试平台跑 case 以及实时做 diff 来断言,最终得到断言结果。chaos 控制台结合测试断言加故障策略命中的日志来判断当前下游接口是强依赖还是弱依赖。
4.2.3 难点
1、java Agent 兼容性
自动化测试平台支持录制回放模式,在回归测试时,可以对某些接口使用事先录制好的流量进行mock,这种模式下会使用基于 jvm-sandbox 的录制回放agent。chaosblade-exec-jvm 也是基于 jvm-sandbox 的agent,2个agent在一起使用会有一些兼容性问题需要解决。
- 两个agent不能同时生效?jvm-sandbox 在1.3.0版本增加 namespace 功能,也就是说可以同时启用多个基于 jvm-sandbox 的 java agent,但是前提条件是 namespace 不同。chaosblade 中默认使用的 default namespace, 通过修改 chaosblade 的中的 namespce 来解决。
- AOP同时切一个Libary的时候,如果mock先生效,故障注入就无效了?在录制回放的agent增加了黑名单的功能来规避这个问题。
2、测试断言和普通测试有区别
使用自动化测试平台做回归测试的时候,更关注是是数据的完整性和准确性,但是在做故障演练的时候,通常是弱依赖已经有问题,除了常规的状态码判断等,对返回结果的判断更多是核心数据节点是否正确。为此在自动化测试平台中单独多了一套断言配置来适配故障演练。
开源贡献
去哪儿网混沌工程的实践过程中主要使用的开源项目是 Chaosblade。在使用过程对 chaosblade、chaosblade-exec-jvm、chaosblade-operator 有不同程度的二次开发和Bug修复,部分修改已经提交给官方repo并merge。同时也和 Chaosblade 社区有过交流沟通,准备进行社区共建,为开源社区贡献自己的一份力量。
未来规划
当前我们的故障演练平台已经支持80+次模拟机房断电演练,同时也已经有500+次日常演练,涉及核心应用50+,机器4000+,业务线也形成了按季度周期演练及上线前验证的良好文化氛围。
我们下一步的主要目标就是自动化线上随机演练,通过服务依赖链路确定最小化爆炸半径,建立线上演练稳态断言,最终实现全司核心页面的全部链路定期随机演练,同时也会发掘混沌工程在服务治理、稳定性建设中的使用场景,为公司业务稳定发展提供技术保障。
“云原生人才计划 2.0”由阿里云、Linux 开源软件学园、马哥教育联合推出,首期内容 “Kubernetes 技术图谱”已在阿里云开发者社区上线,欢迎大家公众号后台回复“人才计划”加入学习,阅读“导读”文档即可了解福利领取方式。