混沌实验模型

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

模型定义

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

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

举个例子:一台 ip 是 10.0.0.1 机器上的应用,调用 [email protected] Dubbo 服务延迟 3s。根据上述的问题列表,先明确的是要对 Dubbo 组件混沌实验,实施实验的范围是 10.0.0.1 单机,对调用 [email protected] 服务模拟 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)的应用,调用 [email protected] (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 模型结构图

为了有个更加直观的认识,我们先通过一下的模型结构图来大致看一下模型之间的关系。核心接口模型是:ExpModelCommandSpec,由它引申出来的是ExpActionCommandSpec和ExpFlagSpec这两个接口。其中,ExpModelCommandSpec已有的具体实现有:cpu、network、disk等;ExpActionCommandSpec则是如cpu下的fullload之类的;ExpFlagSpec是各类自定义参数,比如–timeout。更加详细的模型定义说明请见后续小节。
模型简图

chaosblade 模型定义

type ExpModelCommandSpec interface {
	// 组件名称
	Name() string
	// 支持的场景列表
	Actions() []ExpActionCommandSpec
	// ... 略
}

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

type ExpActionCommandSpec interface {
	// 演练场景名称
	Name() string
	// 规则匹配器列表
	Matchers() []ExpFlagSpec
	// Action 参数列表
	Flags() []ExpFlagSpec
	// Action 执行器
	Executor(channel Channel) Executor
        // ... 略
}

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

type ExpFlagSpec interface {
        // 参数名
	FlagName() string
        // 参数描述
	FlagDesc() string
        // 是否需要参数值
	FlagNoArgs() bool
        // 是否是必要参数
	FlagRequired() bool
}

注: 实验匹配器定义。

chaosblade 模型具体实现

拿 network 组件举例,network 作为混沌实验组件,目前包含网络延迟、网络屏蔽、网络丢包、DNS 篡改演练场景,则依据模型规范,具体实现为:

type NetworkCommandSpec struct {
}
func (*NetworkCommandSpec) Name() string {
	return "network"
}
func (*NetworkCommandSpec) Actions() []exec.ExpActionCommandSpec {
	return []exec.ExpActionCommandSpec{
		&DelayActionSpec{},
		&DropActionSpec{},
		&DnsActionSpec{},
		&LossActionSpec{},
	}
}

network target 定义了 DelayActionSpecDropActionSpecDnsActionSpecLossActionSpec 四中混沌实验场景,其中 DelayActionSpec 定义如下:

type DelayActionSpec struct {
}
func (*DelayActionSpec) Name() string {
	return "delay"
}
func (*DelayActionSpec) Matchers() []exec.ExpFlagSpec {
	return []exec.ExpFlagSpec{
		&exec.ExpFlag{
			Name: "local-port",
			Desc: "Port for external service",
		},
		&exec.ExpFlag{
			Name: "remote-port",
			Desc: "Port for invoking",
		},
		&exec.ExpFlag{
			Name: "exclude-port",
			Desc: "Exclude one local port, for example 22 port. This flag is invalid when --local-port or remote-port is specified",
		},
		&exec.ExpFlag{
			Name:     "device",
			Desc:     "Network device",
			Required: true,
		},
	}
}
func (*DelayActionSpec) Flags() []exec.ExpFlagSpec {
	return []exec.ExpFlagSpec{
		&exec.ExpFlag{
			Name:     "time",
			Desc:     "Delay time, ms",
			Required: true,
		},
		&exec.ExpFlag{
			Name: "offset",
			Desc: "Delay offset time, ms",
		},
	}
}
func (*DelayActionSpec) Executor(channel exec.Channel) exec.Executor {
	return &NetworkDelayExecutor{channel}
}
  • DelayActionSpec 包含 2 个场景参数和 4 个规则匹配器。

总结

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

发表评论