Server/JUnit, Spock

Spring Boot - Chaos Monkey를 활용한 운영 이슈 테스트!

JaeHoney 2022. 6. 11. 20:50

이번 포스팅에선 카오스 엔지니어링을 할 수 있게 도와주는 라이브러리 Chaos Monkey For Spring Boot (CM4SB)에 대해 알아보자.

카오스 엔지니어링

아무리 훌륭한 기업이라도 운영 중인 어플리케이션에 장애 발생은 불가피하다. 이는 자주 접하는 장애일 수도 있고 뜬금없는 장애일 수도 있다. 이러한 장애를 미리 테스트해서 방지하거나 대책을 찾는 것을 카오스 엔지니어링이라고 한다.

 

카오스 엔지니어링 툴은 로컬에서는 경험하기 힘든 아래와 같은 이슈를 미리 확인해 볼 수 있는 툴이다.

  • 네트워크 지연
  • 서버 장애
  • 디스크 오작동
  • 메모리 누수

Chaos Monkey For Spring Boot (CM4SB) 란 ?

Chaos Monkey For Spring Boot (CM4SB)란 Netflix에서 만든 카오스 엔지니어링 툴이다. Chaos Monkey라는 라이브러리를 Spring Boot에서 쉽게 사용할 수 있게 CM4SB라는 라이브러리를 만들어서 배포한다.

 

Chaos Monkey for Spring Boot

https://codecentric.github.io/chaos-monkey-spring-boot/latest/

 

Chaos Monkey for Spring Boot Reference Guide

Chaos Monkey for Spring Boot can be customized to your planned experiment. You can decide which attacks you want to run and which parts of your application should be attacked. Table 1. Main Property Description Values Default chaos.monkey.enabled Determine

codecentric.github.io

동작 방식

카오스 멍키 스프링부트는 쉽게 말하면 앱을 망가뜨리는 역할을 한다. AOP를 이용해서 공격 대상(Watcher)을 활성화한 후 해당 대상이 호출된 경우 활성화된 공격 유형(Assal)t 중 랜덤하게 하나씩 골라서 공격한다.

 

공격 대상 (Watcher)

  • @Controller
  • @Repository
  • @Service
  • @RestController
  • @Component

공격 유형 (Assaults)

  • 응답 지연 (Latency Assault)
  • 예외 발생 (Exception Assault)
  • 애플리케이션 종료 (AppKiller Assault)
  • 메모리 누수 (Memory Assault)

 

아래 그림은 ChaosMonkey의 동작과정을 도식화해서 나타낸 것이다.

애노테이션들이 붙어있는 Bean들의 메소드에 public이 붙여져 있다면 오른쪽의 공격들을 해 볼 수 있다. 응답 지연을 한 번 만들어 보자

 

먼저 CM4SB 모듈 의존성을 추가한다. spring-boot-starter-actuator 의존성도 추가하는데 스프링 부트에서 제공하는 운영에 필요한 다양한 기능을 제공하는 모듈이다. 런타임중에 카오스 몽키 설정을 변경할 수 있다.

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

그리고 application.properties에서 profile에서 카오스 몽키를 활성화해야 한다.

//카오스 몽키 활성화
spring.profiles.active=chaos-monkey

//스프링 부트 Actuator 엔드 포인트 활성화
management.endpoint.chaosmonkey.enabled=true
management.endpoints.web.exposure.include=health,info,chaosmonkey

이제 Repository에 카오스 몽키를 적용해보자. application.properties 파일에 아래의 내용을 추가하면 @Repository 애노테이션이 붙은 클래스에 카오스몽키가 적용된다.

chaos.monkey.watcher.repository=true

그 다음 앱 서버에 http요청을 보내서 카오스 몽키를 활성화 시키면 된다. 이때는 POST /actuator/chaosmonkey/enable로 요청을 보내면 된다.

 

더 많은 기능은 아래 표를 참고하자.

end-point (/actuator) 설명 Method
/chaosmonkey 현재 카오스 멍키 설정 정보 Get
/chaosmonkey/status 카오스 멍키 on/off 여부 Get
/chaosmonkey/enable 카오스 멍키 on Post
/chaosmonkey/disable 카오스 멍키 off Post
/chaosmonkey/watchers 현재 켜져있는 watchers 정보 Get
/chaosmonkey/watchers watchers 정보 수정 Post
/chaosmonkey/assaults 현재 켜져있는 assaults 정보 Get
/chaosmonkey/assaults assaults 정보 수정 Post

이제 GET /watchers로 현재 활성화된 watcher 목록을 볼 수 있다.

이제 Repository에 지연 공격을 해보자. 다음과 같이 요청을 보내면 된다.

POST /actuator/chaosmonkey/assaults
{
    "level": 3,
    "latencyRangeStart": 2000,
    "latencyRangeEnd": 5000,
    "latencyActive": true
}

해당 요청은 아래의 의미를 가진다.

  • level=3: 3번 요청할 때마다 1번씩 공격(지연)하도록 설정
  • latencyRangeStart=2000 latencyRangeEnd=5000: 2초~5초 정도 응답을 지연 시켜라
  • latencyActive=true: 지연 공격을 활성화

이제 JMeter로 테스트를 진행해보자. (JMeter가 뭔지 몰라도 무방하다.)

이제 요청들이 1/3 확률로 지연되는 것을 볼 수 있다. Repository에 지연 공격을 가했는데 요청을 받는 Controller에서 해당 Repository의 결과를 참조하기 때문에 요청에 대한 응답도 지연된다. 그래도 요청이 대체로 성공하는 것을 알 수 있다.

 

공격 대상(Watcher)은 반드시 클래스 또는 애노테이션 단위로 걸지 않아도 된다. 가령 아래와 같이 특정 메서드를 지정할 수도 있다.

POST /actuator/chaosmonkey/assaults
{
  "level": 5,
  "latencyRangeStart": 2000,
  "latencyRangeEnd": 5000,
  "latencyActive": true,
  "exceptionsActive": true,
  "killApplicationActive": false,
  "watchedCustomServices": [
    "com.example.chaos.monkey.chaosdemo.controller.HelloController.sayHello",
    "com.example.chaos.monkey.chaosdemo.controller.HelloController.sayGoodbye"
  ]
}

추가로 우리는 런타임 시점에 HTTP 요청으로 지연 공격에 대해 설정했지만, 그런 부분도 정적으로 yml이나 properties에서 설정할 수도 있다.

 


Reference