Skip to main content
Version: Next

模型篇

遵循此模型,可以简单明了的执行一次混沌实验,控制实验的最小爆炸半径。并且可以方便快捷的扩展新的实验场景或者增强现有场景。chaosbladechaosblade-exec-jvm 工程都根据此模型实现。

模型定义

在给出模型之前先讨论实施一次混沌实验明确的问题:

  • 对什么做混沌实验
  • 混沌实验实施的范围是是什么
  • 具体实施什么实验
  • 实验生效的匹配条件有哪些

举个例子:一台 ip 是 10.0.0.1 机器上的应用,调用 com.example.HelloService@1.0.0 Dubbo 服务延迟 3s。根据上述的问题列表,先明确的是要对 Dubbo 组件混沌实验,实施实验的范围是 10.0.0.1 单机,对调用 com.example.HelloService@1.0.0 服务模拟 3s 延迟。 明确以上内容,就可以精准的实施一次混沌实验,抽象出以下模型:

fault-injection model

  • Target:实验靶点,指实验发生的组件,例如 容器、应用框架(Dubbo、Redis、Zookeeper)等。
  • Scope:实验实施的范围,指具体触发实验的机器或者集群等。
  • Matcher:实验规则匹配器,根据所配置的 Target,定义相关的实验匹配规则,可以配置多个。由于每个 Target 可能有各自特殊的匹配条件,比如 RPC 领域的 HSF、Dubbo,可以根据服务提供者提供的服务和服务消费者调用的服务进行匹配,缓存领域的 Redis,可以根据 set、get 操作进行匹配。
  • Action:指实验模拟的具体场景,Target 不同,实施的场景也不一样,比如磁盘,可以演练磁盘满,磁盘 IO 读写高,磁盘硬件故障等。如果是应用,可以抽象出延迟、异常、返回指定值(错误码、大对象等)、参数篡改、重复调用等实验场景。

回到上述的例子,可以叙述为对 Dubbo 组件(Target)进行故障演练,演练的是 10.0.0.1 主机(Scope)的应用,调用 com.example.HelloService@1.0.0 (Matcher)服务延迟 3s(Action)。

伪代码可以写成:


Toolkit.
// 实验靶点
dubbo.
// 范围,此处是主机
host("1.0.0.1").
// 组件匹配器,消费者还是服务提供者
consumer().
// 组件匹配器,服务接口
service("com.example.HelloService").
// 组件匹配器,1.0.0 接口版本
version("1.0.0").
// 实验场景,延迟 3s
delay(3000);

chaosblade 模型实现

chaosblade cli 调用

针对上述例子,chaosblade 调用命令是:

blade create dubbo delay --time 3000 --consumer --service com.example.HelloService --version 1.0.0
  • dubbo: 模型中的 target,对 dubbo 实施实验。
  • delay: 模型中的 action,执行延迟演练场景。
  • --time: 模型中 action 参数,指延迟时间。
  • --consumer--service--version:模型中的 matchers,实验规则匹配器。

注: 由于 chaosblade 是在单机执行的工具,所以混沌实验模型中的 scope 默认为本机,不再显示声明。

chaosblade 模型结构图

为了有个更加直观的认识,我们先通过一下的模型结构图来大致看一下模型之间的关系。核心接口模型是:ModelSpec,由它引申出来的是FlagSpecActionSpec这两个接口。其中,ModelSpec已有的具体实现有:druid、myql、servlet等;则是如myql下的dalay之类的;FlagSpec是各类自定义参数,比如--time。更加详细的模型定义说明请见后续小节。

chaosblade 模型定义

public interface ModelSpec {
// 组件名称
String getTarget();

// 支持的场景列表
List<ActionSpec> getActionsList<MatcherSpec> getMatchers();

// ... 略
}

注: 一个组件混沌实验模型的定义,包含组件名称和所支持的实验场景列表。

public interface ActionSpec {
// 演练场景名称
String getName();

// 规则匹配器列表
List<MatcherSpec> getMatchers();

// Action 参数列表
List<FlagSpec> getActionFlags();

// Action 执行器
ActionExecutor getActionExecutor();

// ... 略
}

注: 一个实验场景 action 的定义,包含场景名称,场景所需参数和一些实验规则匹配器

public interface FlagSpec {
// 参数名称
String getName();

//参数描述
String getDesc();

//是否有值
boolean noArgs();

//是否必填
boolean required();
}

注: 实验匹配器定义。

chaosblade 模型具体实现

拿 sevlet 组件举例,sevlet 作为混沌实验组件,目前包含延迟、自定义异常抛出,具体实现为:

public class ServletModelSpec extends FrameworkModelSpec {

@Override
public String getTarget() {
return ServletConstant.TARGET_NAME;
}

@Override
public String getShortDesc() {
return "java servlet experiment";
}

@Override
public String getLongDesc() {
return "Java servlet experiment, support path, query string, request method matcher";
}

@Override
public String getExample() {
return "servlet --requestpath /hello --method post";
}

@Override
protected List<MatcherSpec> createNewMatcherSpecs() {
ArrayList<MatcherSpec> matcherSpecs = new ArrayList<MatcherSpec>();
matcherSpecs.add(new ServletQueryStringMatcherSpec());
matcherSpecs.add(new ServletMethodMatcherSpec());
matcherSpecs.add(new ServletRequestPathMatcherSpec());
return matcherSpecs;
}
}

FrameworkModelSpec定义了 DelayActionSpecThrowCustomExceptionActionSpec两种混沌实验场景,其中 DelayActionSpec 定义如下:

public class DelayActionSpec extends BaseActionSpec {

private static TimeFlagSpec timeFlag = new TimeFlagSpec();
private static TimeOffsetFlagSpec offsetFlag = new TimeOffsetFlagSpec();

public DelayActionSpec() {
super(new DefaultDelayExecutor(timeFlag, offsetFlag));
}

@Override
public String getName() {
return "delay";
}

@Override
public String[] getAliases() {
return new String[0];
}

@Override
public String getShortDesc() {
return "delay time";
}

@Override
public String getLongDesc() {
return "delay time...";
}

@Override
public List<FlagSpec> getActionFlags() {
return Arrays.asList(timeFlag, offsetFlag);
}

@Override
public PredicateResult predicate(ActionModel actionModel) {
if (StringUtil.isBlank(actionModel.getFlag(timeFlag.getName()))) {
return PredicateResult.fail("less time argument");
}
return PredicateResult.success();
}
}
  • DelayActionSpec 包含 2 个场景参数和 3个规则匹配器。

总结

通过以上事例,可以看出此模型简单、易实现,并且可以覆盖目前已知的实验场景。后续可以对此模型进行完善,成为一个混沌实验标准。