이번 포스팅에서는 운영 이슈 테스트를 학습할 것이다. HTTP API 요청을 할 때 늘 같은 인터넷 속도와 환경, 그리고 서버의 메모리 상태와 동시 접속하는 사용자는 늘 달라진다. 그렇게 다음과 같은 운영 환경 문제가 발생할 수 있다.
| 네트워크 지연 | 서버 장애 |
| 디스크 오작동 | 메모리 누수 |
이러한 이슈들은 간혹가다 한 번씩 발생을 하지만, 발생했을 때의 여파는 매우 크다.
이렇게 생기는 문제들을 카오스(Chaos)라 하는데, 이런 이슈를 핸들링하는 방법을 카오스 엔지니어링이라 한다.
그리고 이런 카오스 엔지니어링을 도와주는 툴들이 있는데, 대표적으로 넷플릭스에서 만든 Chaos Monkey라는 툴이 있다.
넷플릭스의 카오스 엔지니어링을 설명하기 위한 기본 원칙을 담고 있는 책의 번역본카오스 엔지니어링의 원칙 :: Channy's Blog
Chaos Monkey for Spring Boot를 사용해서 카오스 엔지니어링을 해 볼 것이다.
다음과 같은 어노테이션이 붙어있는 빈(bean)들에 접근제어자가 public인 경우 다음과 같은 공격을 할 수 있으며, Chaos Monkey를 사용해 공격을 해서 카오스 엔지니어링을 진행해 볼 것이다.
| 공격 대상(Watcher) | 공격 유형(Assaults) | ||
|---|---|---|---|
| @RestController | 응답 지연(Latency Assault) | ||
| @Controller | 예외 발생(Exception Assault) | ||
| @Service | 애플리케이션 종료(AppKiller Assault) | ||
| @Repository | 메모리 누수(Memory Assault) | ||
| @Component |
테스트 대상 프로젝트에서 특정 Repository가 응답 지연이 발생한다면 해당 Repository를 사용하는 Service나 Controller도 같이 응답이 지연된다. 이런 상황들을 재연할 수 있다면, 우리는 개발 단계에서 임의의 응답 지연이나 문제가 이슈가 발생하는 대상을 찾을 수 있고, 문제가 없는 Repository로 바꾸거나 성능 개선을 추구할 수 있다.
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>chaos-monkey-spring-boot</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
spring.profiles.active=chaos-monkey
management.endpoint.chaosmonkey.enabled=true
management.endpoints.web.exposure.include=health,info,chaosmonkey
CM4SB(Chaos Monkey For Spring Boot) 라이브러리를 이용해 응답 지연 이슈를 확인해 보자.
우선 프로젝트 설정 파일에서 @Repository 어노테이션에 대해 Watcher를 활성화
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 |
"level": 3 : 3번 요청할 때마다 1번씩 공격(지연) 하도록 설정"latencyRangeStart": 2000 "latencyRangeEnd": 5000 : 2초~5초 응답 지연"latencyActive": true : 지연 공격 활성화
이제 요청들이 1/3 확률로 지연되는 것을 볼 수 있다. Repository에 지연 공격을 가했는데 요청을 받는 Controller에서 해당 Repository의 결과를 참조하기 때문에 요청에 대한 응답도 지연된다. 그래도 요청이 대체로 성공하는 것을 알 수 있다.