Contents
운영 이슈는 로컬이 아닌 운영 환경에서 간혹 발생하지만 문제 여파가 크거나 복구하기 어려운 문제를 미리 제한된 운영환경에서 확인해보는 툴이다. 이를 Chaos 엔지니어링이라고 한다
1. Chaos engineering
운영 환경의 불확실한 예시로는 네트워크 지연, 서버 장애, 디스크 오작동, 메모리 누수 등이 있다.
이런 일들이 갑자기 쌓이거나 트래픽이 갑자기 몰리면 하위 다운 시스템에 무리를 주기도 한다.
이런 혼란을 막기 위해 해결방안을 모색하는 것을 카오스 엔지니어링이라고 한다.
카오스 엔지니어링의 원칙 https://channy.creation.net/blog/1173
카오스 엔지니어링의 원칙 :: Channy's Blog
차니 블로그(Channy Blog)는 웹기술, 오픈소스, 클라우드 컴퓨팅 등 다양한 IT 기술 주제에 대해 다루고 있습니다.
channy.creation.net
2. Chaos Monkey
카오스 몽키는 프로덕션 환경, 특히 분산 시스템 환경에서 불확실성을 파악하고 해결 방안을 모색하는데 사용하는 대표적인 툴이다.
넷플릭스에서 만든 툴이다.
https://netflix.github.io/chaosmonkey/
카오스 멍키 스프링 부트
https://codecentric.github.io/chaos-monkey-spring-boot/latest/#getting-started
카오스 멍키 스프링부트는 스프링 부트 애플리케이션에 카오스 멍키를 손쉽게 적용해 볼 수 있는 툴이다.
즉, 스프링 부트 애플리케이션을 망가트릴 수 있는 툴이다.
주요 개념
대상(Restcontroller, contoroller, service, repository, component)에 공격(응답지연, 예외발생, 어플리케이션 종료, 메모리누수)을 가해볼 수 있다. 이러한 상황을 재현을 해 본 후 대안을 찾는 방식이다.
예시로 컨트롤러 응답이 느려지면 다른 서비스나 respository쓴다든가 하는 방식으로 어플리케이션을 탄탄하게 만들 수 있다. 소스코드를 건드리지 않고 재현해볼 수 있어서 좋다.
공격 대상 (Watcher)
- @RestController
- @Controller
- @Service
- @Repository
- @Component
공격 유형 (Assaults)
- 응답 지연 (Latency Assault)
- 예외 발생 (Exception Assault)
- 애플리케이션 종료 (AppKiller Assault)
- 메모리 누수 (Memory Assault)
3. Chaos Monkey for Spring boot 설치
1) 의존성 추가
(1) Chaos-monkey-spring-boot : 스프링 부트용 카오스 멍키 제공
(2) Spring-boot-starter-actuator
- 스프링 부트 운영 툴로, 다양한 모듈들을 지원한다. 런타임 중에 카오스 멍키 설정을 변경할 수 있다.
- 그밖에도 헬스 체크, 로그 레벨 변경, 매트릭스 데이터 조회 등 다양한 운영 툴로 사용 가능.
- Maven
<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>
- Gradle
implementation group: 'de.codecentric', name: 'chaos-monkey-spring-boot', version: '3.0.1'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: '3.1.0'
2) 활성화
카오스 몽키를 활성화해야 실행이 된다
(1) 카오스 몽키 활성화
application.properties 파일에 아래 내용을 적어준다.
spring.profiles.active=chaos-monkey
또는 intellij나 개발툴의 실행 프로필(active profiels)에서 입력해준다.
(2) 스프링 부트 Actuator 엔드 포인트 활성화
역시 application properties에서 아래 내용을 추가한다.
management.endpoint.chaosmonkey.enabled=true
management.endpoints.web.exposure.include=health,info,chaosmonkey
management:
endpoint:
chaosmonkey:
enabled: true
endpoints:
web:
exposure:
include: health,info,chaosmonkey
어플리케이션을 실행하면 카오스 몽키 로고가 나타난다
3. 예시1 - 응답 지연
우선 cmd에서 jmeter로 테스트를 실행시켜둔다.
1) Repository Watcher 활성화
application.properties에 repository에 대한 watcher를 활성화해둔다
chaos:
monkey:
watcher:
repository: true
chaos.monkey.watcher.repository=true
@repository 어노테이션이 붙은 빈들에 카오스 몽키를 적용한다.
JpaRepository 기본 구현체에 repositoy라는 어노테이션이 붙어있기 때문에, 실제로 적용이 된다.
2) 카오스 멍키 활성화
postman등을 이용해서 해당 url을 실행한다
POST
localhost:8080/actuator/chaosmonkey/enable
3) 카오스 멍키 활성화 확인
GET
localhost:8080/actuator/chaosmonkey/status
4) 카오스 멍키 와처 확인
GET
localhost:8080/actuator/chaosmonkey/watchers
원래는 service도 기본 true로 되어있다는데 안되어있으므로, 필요하다면 application.properties에서 repository처럼 명시적으로 true로 변경해준다.
활성화는 runtime 중에 적용되지 않으나, 끄는 것은 가능하다. POST로 body를 넣어서 변경해준다.
localhost:8080/actuator/chaosmonkey/watchers
그래도 가능하면 watcher에 대한 설정은 properties에서 해준다.
5) 카오스 멍키 지연 공격 설정
http POST
localhost:8080/actuator/chaosmonkey/assaults
level은 2번 요청할 때 마다 1번씩 공격,
LatencyRangeStart - LatendyRageEnd는 2초에서 5초 사이에 공격을 하라는 뜻이다
6) 테스트
JMeter 확인해보면 시간 지연이 일어나는 것을 볼 수 있다.
- 기존 테스트 결과
- Choas monkey 공격 후 시간
Min 시간은 어차피 최소이기 떄문에 큰 차이가 나지 않고, max에서 차이가 난다
실행을 계속 하면 평균값이 올라가는 걸 확인할 수 있을 것이다.
이러한 응답 지연은 A서버에서 B1, B2서버를 호출 할 때, 응답이 빠른 서버 위주로 호출해야한다고 하면
B1 서버에 카오스 몽키로 지연을 일으켜서, B2서버를 호출하는지 확인하면 된다.
cf) watchedCustomServices 특정 메소드 지정
위에서는 Repository에 모두 적용하게 했는데, 특정 메소드에만 적용하게 하는 것도 가능하다.
"watchedCustomServices"에 해당 메소드를 적어주면 된다.
{
"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"
]
}
또는 런타임 뿐만 아니라 config로 지정해줄 수도 있다.
chaos:
monkey:
watcher:
repository: true
assaults:
watched-custom-services: "com.example.chaos.monkey.chaosdemo.controller.HelloController.sayHello"
4. 예시2 - 에러 발생
해당 url의 repository에서 에러가 발생하는 경우를 테스트한다고 가정한다.
@GetMapping("/team/{id}")
public Team getTeam(@PathVariable Long id){
return repository.findById(id).orElseThrow(()->new IllegalArgumentException("Team not found for " + id));
}
이 경우도 A서버의 B1서비스를 쓸 떄 에러가 난다면, B2 서비스를 쓰는 식으로 대체할 수 있다.
이를 위해 B1 서비스에 에러를 내서 테스트를 해본다.
에러 설정
localhost:8080/actuator/chaosmonkey/assaults

다시 설정을 해주면 50%의 확률로 에러가 나는 것을 볼 수 있다.
출처 : '더 자바, 애플리케이션을 테스트하는 다양한 방법'(백기선), 자료&33~36강
'Java & Spring' 카테고리의 다른 글
[Java Test] 6. ArchUnit 아키텍처 테스트 (0) | 2023.05.26 |
---|---|
[Java Test] 4. Jmeter 성능테스트 (0) | 2023.05.25 |
[Java Test] 2. Mockito (0) | 2023.05.22 |
[Java Test] 1. JUnit5 (4) properties, 확장, 마이그레이션 (0) | 2023.05.22 |
[Java Test] 1. JUnit5 (3) 테스트 인스턴스 & 순서 지정 (0) | 2023.05.19 |
[Java Test] 1. JUnit5 (2) 테스트 필터링, 테스트 반복 (1) | 2023.05.19 |
[Java Test] 1. JUnit5 (1) (0) | 2023.05.18 |
[DDD] 도메인 주도 개발 - (3) 리포지토리 & 모델 구현 (0) | 2023.02.21 |