본문 바로가기

spring

chaos engineering과 chaos monkey 사용법

chaos engineering이란?

chaos engineering은 시스템의 안정성을 테스트하고 향상시키기 위한 실험적인 방법론입니다. 다양한 장애 상황을 인위적으로 만들어 시스템이 어떻게 반응하는지 관찰하고, 예측하지 못한 장애 상황에서도 시스템이 정상적으로 동작하게 만들도록 준비할 수 있습니다.

chaos engineering이 필요한 이유

꼬리 지연 등으로 인해 한 시스템의 장애가 다른 시스템으로 전파될 수 있는데, 장애 상황을 미리 경험하고 대응책을 마련함으로써 실제 장애 발생 시 효율적으로 대응할 수 있습니다. 또한 시스템의 고가용성을 유지하고 서비스 중단 시간을 최소화하여 안정적인 서비스를 제공할 수 있습니다.

Chaos Monkey

Netflix에서 chaos engineering을 위해 개발한 툴입니다. choas monkey 공식 사이트를 보면 다음과 같이 소개가 나와 있습니다.

Chaos Monkey is responsible for randomly terminating instances in production to ensure that engineers implement their services to be resilient to instance failures.

Chaos Monkey는 인스턴스 장애에 대한 서비스의 탄력성을 테스트하기 위해 프로덕션 환경에서 무작위로 인스턴스를 종료합니다. 이 도구는 Netflix의 엔지니어링 팀에 의해 개발되었으며, 시스템이 예기치 않은 인스턴스 종료에도 견딜 수 있도록 보장합니다. 이를 통해 서비스의 가용성과 신뢰성을 높이는 데 도움이 됩니다.

Chaos Monkey 사용법

Spring Boot로 server를 하나 실행시켜 간단하게 controller를 만들고 chaos monkey를 활성화 시켰을 때와 정상 상태를 비교해보고자 합니다. chaos monkey를 이용해 latency, memory leak, cpu overload, exception, application killed 등의 장애 상황을 재현할 수 있는데, 이번 글에서는 간단하게 latency가 생기는 상황을 재현해보고자 합니다.

프로젝트 생성

간단하게 spring boot starter로 Controller를 하나 만들었습니다. 단순히 'ok'를 반환하는 rest controller입니다.

@RestController
@RequiredArgsConstructor
@Slf4j
public class PerformanceController {

    @GetMapping("/performance")
    public String perform() {
        log.info("performance controller called");
        return "ok";
    }
}

 

요청을 보내보면 단순히 ok 반환하는 컨트롤러이기 때문에 latency 5ms로 거의 존재하지 않습니다. 요청은 단순히 웹이나 curl로 보내도 되지만, jmeter를 활용하여 테스트를 했습니다. jmeter 활용법은 이전 글을 참고하시기 바랍니다.

 

chaos monkey 사용을 위한 dependency 추가

build.gradle에 다음과 같이 의존성을 추가하였습니다. chaos monkey를 사용하기 위해선 actuator가 필요하여 추가로 설정하였습니다.

//...

implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'de.codecentric:chaos-monkey-spring-boot:3.1.0'

CM4SB를 설정할 때 버전을 명시하지 않으면 project를 가져올 수 없다고 하는데, maven central에서 필요한 버전을 찾아 명시하면 됩니다.

application 설정

spring:
  profiles:
    active: chaos-monkey

chaos:
  monkey:
    watcher:
      rest-controller: true

management:
  endpoint:
    chaosmonkey:
      enabled: true
  endpoints:
    web:
      exposure:
        include: chaosmonkey
  • chaos monkey 설정을 위한 profile을 chaos-monkey로 설정합니다.
  • watcher를 설정해서 rest-controller에서만 동작하게 만듭니다.
  • endpoint로 chaos monkey의 endpoint에 접근가능하도록 활성화합니다.
  • web에서도 chaos monkey에 접근 가능하도록 설정해줍니다.

choas monkey 설정 및 확인

actuator endpoint를 통해  chaos monkey에 대한 설정을 직접 할 수 있고 확인도 할 수 있습니다. 위에서 의존성과 설정을 모두 한 후 서버를 실행하면 다음의 endpoint를 통해 chaos monkey에 대한 설정을 확인할 수 있습니다.

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

  • chaos monkey를 아직 활성화하지 않았기 때문에 enabled는 false로 나옵니다.

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

  • rest-controller만 watcher로 설정하였으므로 restController만 true입니다.

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

  • assaults에 대한 기본 설정입니다. 아직 공격 타입을 active 상태로 바꾸지 않았기 때문에 모두 false입니다. 해당 endpoint로 body에 값을 담아 post 요청을 보내면 configuration이 변경됩니다.
  • 현재 latencyActive, exceptionsActive, memoryActive, cpuActive가 모두 false인 상태입니다.

이제 설정을 모두 활성시키도록 하겠습니다.

  • POST http://localhost:8080/actuator/chaosmonkey/enable
  • POST http://localhost:8080/actuator/chaosmonkey/assaults { "latencyActive": true }

GET 요청으로 다시 상태를 확인해보면 enabled=true, latencyActive=true를 확인할 수 있습니다.

latency test

다시 jmeter로 요청을 보내도록 하겠습니다. 요청은 thread 수를 10으로 하여 동시 요청을 보냈습니다.

  • 요청 하나의 latency가 1666ms인 것을 볼 수 있습니다.
  • summary report를 확인해보면 average 932ms, max 2696ms인 것을 확인할 수 있습니다.
  • latencyRangeStart, latencyRangeEnd가 1000~3000으로 설정되어 있어 랜덤하게 latency가 발생했을 때의 상황을 확인해볼 수 있었습니다.(기존에 latency 없이 보냈던 요청 sample로 인해 avg. 932가 발생)