混沌工程测试工具:chaosblade:基础命令

安装 blade cli

获取 chaosblade 最新的 release 包,目前支持的平台是 linux/amd64 和 darwin/64,下载对应平台的包。 下载完成后解压即可,无需编译。

wget https://chaosblade.oss-cn-hangzhou.aliyuncs.com/agent/github/0.10.0/chaosblade-0.10.0-linux-amd64.tar.gz && mkdir -p ./chaosblade && tar -xzvf chaosblade-0.10.0-linux-amd64.tar.gz -C ./chaosblade --strip-components 1 && export PATH=$PATH:./chaosblade

基础资源:比如 CPU、内存、网络、磁盘、进程等实验场景;

场景一:服务器CPU爆满

$ ./blade create cpu fullload {"code":200,"success":true,"result":"a0682a98d0d7d900"}

场景二:服务器磁盘爆满

./blade create disk fill -d --mount-point /bladedisk --size 1024

场景三:服务器网络缓慢

Chaosblade也可以对网络进行控制,比如运行下面命令可以限制经过eth0网卡的网络都会延迟3秒:

./blade create network delay --interface eth0 --time 3000

它实际是利用的linux系统下的tc(Traffic Control)命令

Java 应用:比如数据库、缓存、消息、JVM 本身、微服务等,还可以指定任意类方法注入各种复杂的实验场景;

场景四:调用某个Dubbo服务超时

启动

`dubbo-provider nohup java -Djava.net.preferIPv4Stack=true -Dproject.name=dubbo-provider -jar dubbo-provider-1.0-SNAPSHOT.jar > provider.nohup.log 2>&1 &` 

稍等 2 秒,然后启动

dubbo-consumer nohup java -Dserver.port=8080 -Djava.net.preferIPv4Stack=true -Dproject.name=dubbo-consumer -jar dubbo-consumer-1.0-SNAPSHOT.jar > consumer.nohup.log 2>&1 &

进行故障演练:
挂载agent

$ ./blade prepare jvm --process dubbo.consumer 

{“code”:200,“success”:true,“result”:“5cdbc31f46a3d621”}

`$ ./blade create dubbo delay --time 3000 --service com.alibaba.demo.HelloService --methodname hello --consumer --process dubbo.consumer

{“code”:200,“success”:true,“result”:“3e705e8babe8a86c”}

场景五:JVM中某个方法抛出异常或者修改方法返回值

Chaosblade支持直接操作jvm中的方法,使它抛出异常或修改其返回值。先准备一个MockJvm类:

package com; 
import java.util.concurrent.TimeUnit; 
public class MockJvm { 
	public String test() { 
		return "test..."; 
				} 
	public static void main(String[] args) throws InterruptedException { 
	MockJvm testJVM = new MockJvm(); 
	while (true) { 
		try { 
			System.out.println(testJVM.test()); 
			} 
		catch (Exception e) {
			System.out.println(e.getMessage()); 
		} 
		TimeUnit.SECONDS.sleep(3); 
		} 
	} 
}

这个类会每隔三秒调用一下test方法,并打印出方法的返回值,并且在捕获test方法所抛出的异常进行打印,test方法默认返回"test"。我们运行这个类,让这个类一直在运行状态,正常运行时,控制台会打印如下:

test… test… test… test…

方法抛出异常

`$ ./blade prepare jvm --process MockJvm` 

{“code”:200,“success”:true,“result”:“5ff98509d2334906”}

$ ./blade create jvm throwCustomException --process MockJvm --classname com.MockJvm --methodname test --exception java.lang.Exception 

{“code”:200,“success”:true,“result”:“f9052478db2f7ffc”}

上面的命令模拟了MockJvm进程下的com.MockJvm类中的test方法会抛出java.lang.Exception异常。一旦这个命令执行成功,那么我们上面一直在运行的代码控制台将抛出异常:

test… test… test… chaosblade-mock-exception chaosblade-mock-exception

使用以下命令可以撤回刚刚的场景模拟:

./blade destroy f9052478db2f7ffc 

修改方法的返回值

使用以下命令可以修改方法的返回值:

`$ ./blade create jvm return --process MockJvm --classname com.MockJvm --methodname test --value hahaha...` 

{“code”:200,“success”:true,“result”:“9ffce12b1fdc2580”}

控制台将打印出:
test…
test…
test…
hahaha…
hahaha…
hahaha…

场景六:调用Mysql超时或出现异常

Chaosblade目前支持Mysql场景分为调用Mysql超时或者执行语句时出现异常。但是它是在JDBC这一层进行控制的,并没有真正的去控制mysql服务端。

这里先用JDBC写一个测试类:

public class JDBCConnection {
public static String url_encrypt="jdbc:mysql://127.0.0.1:3306/test?useSSL=false";
public static String user="数据库名"; 
public static String password="密码";
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url_encrypt,user,password);
Statement stmt= conn.createStatement();
while (true) {
try {
LocalDateTime before = LocalDateTime.now();
ResultSet rs = stmt.executeQuery("select * from t_test");
LocalDateTime after = LocalDateTime.now();
System.out.println("执行时间:" + (after.getSecond() - before.getSecond()));
} catch (Exception e) {
System.out.println(e.getMessage()); }
TimeUnit.SECONDS.sleep(3); }
}
}  

这个测试的功能是去进行select查询,并且如果在select的时候如果抛出异常会被捕获并且进行打印,并且还会计算select语句执行所花费的时间。

首先将上面的类运行起来,控制台将一直打印如下:

执行时间:0
执行时间:0
执行时间:0

调用Mysql抛出异常

运行下面的命令开始故障模拟:

$ ./blade prepare jvm --process JDBCConnection 

{“code”:200,“success”:true,“result”:“f278e66ddb1b4e11”}

`$ ./blade create mysql throwCustomException --database test --host 127.0.0.1 --port 3306 --process JDBCConnection --sqltype select --table t_test --exception java.lang.Exception

{“code”:200,“success”:true,“result”:“ddd6799da50f9201”}
命令执行成功后,控制台将打印出异常:

执行时间:0
执行时间:0
执行时间:0
Unexpected exception encountered during query. Unexpected exception encountered during query.

使用以下命令可以撤回刚刚的场景模拟:

./blade destroy ddd6799da50f9201

调用Mysql增加延迟

直接使用以下命令将使得在执行select时增加4秒的延时,注意都是在JDBC层控制的。

$ ./blade create mysql delay --database test --host 127.0.0.1 --port 3306 --process JDBCConnection --sqltype select --table t_test --time 4000

{“code”:200,“success”:true,“result”:“8e5b35e76098caab”}
命令执行完成后,控制台将打印出:

执行时间:0
执行时间:0
执行时间:4
执行时间:4
执行时间:4

容器

场景七:容器CPU 使用率 80% 的实验场景

 blade create docker cpu fullload --cpu-percent 80 --blade-tar-file /root/chaosblade-0.4.0.tar.gz --container-id 5239e26f6329

–blade-override 是否覆盖容器内已有的 chaosblade 工具,默认是 false,表示不覆盖,chaosblade 在容器内的部署路径为 /opt/chaosblade

–blade-tar-file string 指定本地 chaosblade-VERSION.tar.gz 工具包全路径,用于拷贝到容器内执行
–container-id string 目标容器 ID
–docker-endpoint string Docker server 地址,默认为本地的 /var/run/docker.sock

场景八:容器内网络实验场景

blade create docker network delay 容器网络延迟
blade create docker network loss 容器网络丢包
blade create docker network dns 容器内域名访问异常

对 nginx 容器 80 端口做访问延迟 3 秒,执行命令如下:

blade create docker network delay --time 3000 --interface eth0 --local-port 80 --container-id 5239e26f6329

场景九:容器内进程场景,同基础资源进程场景

blade create docker process kill, 杀容器内指定的进程
blade create docker process stop,挂起容器内指定的进程

杀掉容器内 nginx 进程

blade create docker process kill --process nginx --blade-tar-file /root/chaosblade-0.4.0.tar.gz --container-id ee54f1e61c08

场景十:container 资源自身的场景

blade create docker container remove 删除容器
blade create docker container remove --container-id a76d53933d3f

你可能感兴趣的:(混沌工程,混沌工程,chaosblade,破坏性测试,软件测试)