什么是混沌工程
混沌工程的核心是通过实验的方式来验证系统在稳定下下它的不稳定性,从而通过混沌工程实验的方式来模拟这种情况并给出合理的解决方案,所以它最重要的不是混沌实验,而是实验背后的解决方案。业内最早实践混沌工程的公司是Netfix,混沌工程具体它的定义为:“混沌工程是一门在系统上进行实验的科学,目的是建立系统抵御生产环境中失控情况的能力以及信心”。比如在生产环境中数据库的实例突然瘫痪,云服务器的实例突然消失以及底层服务出现雪崩等等一系列的故障情况下,这个时候整个系统层面需要考虑的是出现这种极端以及很平常的故障下,如何使用技术的手段来保障系统依然能够给客户提供价值从而保障系统的可用性,特别是在分布式架构下服务复杂的调用链以及涉及众多中间件,更加需要考虑在异常的情况下系统的伸缩性和高可用性。
混沌工程的原则
混沌工程首先它是体系化下的实验,不是杂乱无章的,混沌的状态恰恰是系统在稳定性下延伸出的不稳定性,也就是说系统本身是有序的和稳定性。那么在这种情况下进行混搭实验需要遵守混沌工程的原则,这些原则具体为:
- 定义系统稳定的边界。也就是建立关于系统的稳定状态
- 多样化的引入现实世界的真实案例事件。比如雪崩,数据库调用延迟,系统资源出现瓶颈,内存泄露,Redis调用延迟,磁盘无可用的空间等等一系列真实的故障案例
- 在生产环境中运行。这点需要特别的强调下,直接在生产环境中运行是非常不负责的一种行为,所以正确的姿势先在测试环境进行混沌实验,随着实验的成熟再在生产环境中实验,但是前提是这个时候必须得具备应对系统故障时的解决方案和能力。所以这个过程可以理解为在测试环境中不断实验来验证解决方案的成熟度,待解决方案达到满意的情况下再在生产环境中进行混沌实验来验证解决方案在生产环境中的表现和应对故障的能力。
- 混沌实验最好持续的自动化。手动模式的混沌实验具有不可靠性,以及无法持续的执行,所以随着实验的成熟可以把这部分进行持续的推动自动化模式来进行
- 最小爆炸路径。混沌实验的目的是使用可能出现的故障来考验系统的可用性和伸缩性,因此在混沌实验中尽量保持最小路径的实验,防止由于混沌实验导致系统出现大面积的瘫痪从而出现人为引发的故障。
混沌实验的选择性工具是非常多,在文章中主要介绍阿里巴巴开源的ChaosBlade,下来详细的介绍下该工具的下载以及搭建。在被搭建的终端系统中保持已搭建Java环境。
ChaosBlade搭建
在github中下载chaosblade-1.6.1-linux-amd64.tar.gz,下载成功后直接解压并且搭建到PATH的环境变量。输入blade -h 出现如下显示说明ChaosBlade环境已搭建配置成功,具体如图所示。
下面详细地介绍了ChaosBlade经常使用到的参数,具体总结如下:
- --timeout:该参数主要设置场景运行时持续的时间,单位是秒
- --effect-percent:该参数设置请求百分比,范围是0-100
- --effect-count:该参数是设置请求条数限制
数据库调用延迟
下来进行具体的混沌实验最佳实践。在客户端高并发的情况下,数据库在这个过程中可能就会出现调用延迟,出现这种情况导致的结果是客户端向服务端发送请求后,由于DB层面调用延迟从而导致系统响应时间超过系统设置的边界,给客户端带来很差劲的用户体验,那么这个时候解决的方案是在这种高并发的情况下,可以限制客户端的入口流量使用队列的方式服务端依次来处理客户端的请求。下面通过具体的案例来实验这部分(案例代码比较简单,结合SpringBoot与MyBatis,调用接口获取所有书籍的数据来自数据库),实验的具体步骤汇总为如下:
- 启动SpringBoot的应用程序,获取应用程序的PID
- 接着挂载Java Agent
- 模拟数据库的延时
- PostMan调用接口验证响应时间延迟
- 销毁实验场景
结合上面的步骤,下来详细地演示下这部分的操作,具体如下:
代码语言:javascript复制#启动SpringBoot应用程序
java -jar DBPlus-0.0.1-SNAPSHOT.jar
#获取应用程序PID
[root@k8s-node1 ~]# ps -aux | grep DBPlus-0.0.1-SNAPSHOT.jar
root 3536 99.4 8.3 3441644 325568 pts/0 Sl 18:53 0:09 java -jar DBPlus-0.0.1-SNAPSHOT.jar
root 3648 0.0 0.0 112812 1000 pts/1 R 18:53 0:00 grep --color=auto DBPlus-0.0.1-SNAPSHOT.jar
模拟数据库延迟前调用API查看响应时间,具体如下图所示。
下面开始挂载Java Agent和模拟数据库的延迟,具体操作命令如下:
代码语言:javascript复制#挂载Java Agent
[root@k8s-node1 ~]# blade prepare jvm --pid 3536
{"code":200,"success":true,"result":"c0a76d57ac9c9bac"}
#模拟数据库延迟 数据库是book,表是books 业务是select 数据库延迟时间是3s
[root@k8s-node1 ~]# blade create mysql delay --time 3000 --database book --port 3306 --sqltype select books --pid 3536
{"code":200,"success":true,"result":"8dc315383559b58b"}
下来再次在PostMan调用API查看响应时间,具体如下图所示。
在如上截图中,可以看到再次调用API很明显响应时间是很长的,在Druid的平台中也可以看到该API的响应时间,具体如下图所示。
下来是销毁实验,设计命令具体如下:
代码语言:javascript复制[root@k8s-node1 ~]# blade destroy 8dc315383559b58b
{"code":200,"success":true,"result":{"target":"mysql","action":"delay","flags":{"database":"book","pid":"3536","port":"3306","sqltype":"select","time":"3000"},"ActionProcessHang":false}}
混沌实验思考
混沌实验的核心不是混沌实验的过程,而是使用混沌实验的过程来模拟系统的故障从而让研发团队来思考在真实的生产环境中出现这种情况,研发团队如何能够快速的发现问题以及快速的解决问题,以及解决问题是成熟方案是什么,这是混沌实验的核心和终极目标。比如在如上实验模拟数据库的延迟,这个时候用户的体验是非常差劲的,获取任何一个数据以及加载一个数据,响应时间都超过了用户的最佳体验,那么用户的选择是放弃这个产品选择竞争对手的产品来使用。比如针对如上的问题,需要让研发团队第一时间知道问题就得自动触发报警机制,在触发报警机制的情况下能够针对这种机制建立行之有效的流程和快速解决问题的第一负责人以及能够解决问题的第一负责人,或者系统自动开启切换到新的数据引擎的实例,以及针对DB层面考虑到可能DB由于它本身的系统瓶颈导致查询SQL很慢的情况下,是否使用缓存层以及其他技术处理更好,从而减少对数据库的调用。所以混沌实验的核心不是过程,而是通过过程建立一个成熟度的针对故障的技术解决方案和高效敏捷的团队能够在出问题下紧密的合作解决问题。感谢您的阅读,后续持续更新!