Spring/Springboot 是使用非常广泛的 JAVA 框架,所以通过使用 chaostoolkit 的插件 chaostoolkit-spring
来进行 springboot restful api 的混沌工程实验.

Install Chaostoolkit-Spring

pip install -U chaostoolkit-spring

Chaostookit 在 Springboot 项目中的使用

首先这个实验依赖于chaos-monkey-spring-boot 这个项目,chaos toolkit 通过具有这个 lib 报的 springboot 项目交换。
这个交互主要是通过 spring boot actuator HTTP endpoints 进行。

所以在进行 chaos 实验之前,我们先添加一个 springboot 的项目来做模拟:创建 spring 项目不具体展开, 几个关键点是:

<dependency>
           <groupId>de.codecentric</groupId>
           <artifactId>chaos-monkey-spring-boot</artifactId>
           <version>2.0.2</version>
           <exclusions>
               <exclusion>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-starter-actuator</artifactId>
               </exclusion>
           </exclusions>
  </dependency>
spring.profiles.active=chaos-monkey
chaos.monkey.enabled=true

chaos.monkey.watcher.controller=false
chaos.monkey.watcher.restController=true
chaos.monkey.watcher.service=true
chaos.monkey.watcher.repository=false
@GetMapping("/HelloWorld/{id}")
public BaseResponse getHelloWorld(@PathVariable Long id) {
    return BaseResponse.OK().data(HelloWorldDTO.builder().id(id).msg("Hello World").build());

}


@PostMapping("/HelloWorld")
public BaseResponse<HelloWorldDTO> createHelloWorld(@RequestBody HelloWorldDTO requestBody) {
    return BaseResponse.OK().data(requestBody);
}

@PutMapping("/HelloWorld/{id}")
public BaseResponse<HelloWorldDTO> updateHelloWorld(@PathVariable Long id, @RequestBody HelloWorldDTO updateData) {

    return BaseResponse.OK().data(updateData);
}

@DeleteMapping("/HelloWorld/{id}")
public BaseResponse<HelloWorldDTO> deleteHelloWorld(@PathVariable Long id) {
    return BaseResponse.OK().data(HelloWorldDTO.builder().id(id).msg("deleted!").build());
}

GET: http://localhost:8080/actuator/chaosmonkey

如果有返回说明设置成功了:

{
    "chaosMonkeyProperties": {
        "enabled": true
    },
    "assaultProperties": {
        "level": 5,
        "latencyRangeStart": 1000,
        "latencyRangeEnd": 3000,
        "latencyActive": true,
        "exceptionsActive": false,
        "exception": {
            "type": null,
            "arguments": null
        } ......
    }
  }

choas experiment 设置

spring experiment:

{
  "version": "1.0.0",
  "title": "springboot-chaos-monkey try",
  "description": "springboot chaos monkey usage",
  "tags": [
    "springboot"
  ],
  "steady-state-hypothesis": {
    "title": "Application responds",
    "probes": [

      {
        "type": "probe",
        "name": "call localhost url hello world",
        "tolerance": 200,
        "provider": {
          "type": "http",
          "timeout": 3,
          "url": "http://localhost:8080/HelloWorld/1"
        }
      }
    ]
  },
  "method": [
    {
      "name": "configure_assaults",
      "provider": {
        "arguments": {
          "base_url": "http://localhost:8080/actuator",
          "assaults_configuration": {
            "level": 5,
            "latencyRangeStart": 2000,
            "latencyRangeEnd": 5000,
            "latencyActive": true,
            "exceptionsActive": false,
            "killApplicationActive": true,
            "restartApplicationActive": false
          }
        },
        "func": "change_assaults_configuration",
        "module": "chaosspring.actions",
        "type": "python"
      },
      "type": "action"
    }
  ],
  "rollbacks": [
    {
      "name": "disable_chaosmonkey",
      "provider": {
        "arguments": {
          "base_url": "http://localhost:8080/actuator"
        },
        "func": "disable_chaosmonkey",
        "module": "chaosspring.actions",
        "type": "python"
      },
      "type": "action"
    }
  ]
}

结果:

(chaos-toolkits) ➜  chaos-toolkits git:(master) ✗ chaos run spring-experiment.json
[2019-05-21 14:38:00 INFO] Validating the experiment's syntax
[2019-05-21 14:38:00 INFO] Experiment looks valid
[2019-05-21 14:38:00 INFO] Running experiment: springboot-chaos-monkey try
[2019-05-21 14:38:00 INFO] Steady state hypothesis: Application responds
[2019-05-21 14:38:00 INFO] Action: enable_chaosmonkey
[2019-05-21 14:38:00 CRITICAL] Steady state probe 'enable_chaosmonkey' is not in the given tolerance so failing this experiment
[2019-05-21 14:38:00 INFO] Let's rollback...
[2019-05-21 14:38:00 INFO] Rollback: disable_chaosmonkey
[2019-05-21 14:38:00 INFO] Action: disable_chaosmonkey
[2019-05-21 14:38:00 INFO] Experiment ended with status: failed

chaos-spring 源码说明

chaos-spring 代码分析, 实际上 chaos-spring 代码不多,很容易理解

  tree .
.
├── __init__.py
├── actions.py
├── api.py
└── probes.py

实际上总过就是这三个文件.

api: 文件是访问 api chaos-monkey 的接口调用
probes: 用来定义 probes 的方法,下面的例子这个就可以在 experiment.json 中定义了 assaults_configuration可以使用在

```python

def assaults_configuration(base_url: str,
                           headers: Dict[str, Any] = None,
                           timeout: float = None,
                           configuration: Configuration = None,
                           secrets: Secrets = None) -> Dict[str, Any]:
    """
    Get the current assaults configuraton from the specified service.
    """

    response = api.call_api(base_url=base_url,
                            api_endpoint="chaosmonkey/assaults",
                            headers=headers,
                            timeout=timeout,
                            configuration=configuration,
                            secrets=secrets)

    if response.status_code != codes.ok:
        raise FailedActivity(
            "ChaosMonkey assaults enquiry failed: {m}".format(m=response.text))

    return response.json()

简单使用 spring 的这个介绍就到这里,后续会进行说明如何使用 actions/probes 原理的介绍.


↙↙↙阅读原文可查看相关链接,并与作者交流