장애 주입 시험
단절은 docker pause, 지연과 손실은 tc netem, 중복은 동일 메시지 재전송으로 주입하여 복구 동작을 확인한다.
장애 주입의 목적
정상 흐름만 시험하면 재연결, timeout, 중복 처리 코드는 한 번도 실행되지 않은 상태로 남는다. 이러한 코드는 장애가 발생했을 때에만 실행된다. 장애 주입 시험은 시험 환경에서 단절, 지연, 중복을 의도적으로 발생시켜 그 코드를 실행하는 시험이다.
단절: docker pause
docker pause는 컨테이너 내부의 모든 프로세스를 정지시킨다. 프로세스를 종료하지 않고 정지만 시키므로, 컨테이너는 실행 중이지만 응답하지 않는 상대가 된다. Linux에서는 freezer cgroup을 사용하므로 프로세스는 자신이 정지되었음을 감지하지 못한다.
docker pause broker
# timeout과 재연결 시도를 지켜본 뒤 되돌린다
docker unpause broker
지연과 손실: tc netem
netem은 네트워크 장치에서 송신되는 패킷에 지연, 손실, 중복, 손상을 주입하는 Linux 큐 규칙(qdisc)이다.
# 나가는 패킷을 100ms(±10ms) 늦춘다
sudo tc qdisc add dev eth0 root netem delay 100ms 10ms
# 지연은 두고 패킷의 1%를 버리게 바꾼다
sudo tc qdisc change dev eth0 root netem delay 100ms 10ms loss 1%
# 되돌린다
sudo tc qdisc del dev eth0 root
delay 시간 [지터]: 패킷을 지정한 시간만큼 지연시켜 송신한다.loss 비율: 패킷을 무작위로 폐기한다.duplicate 비율: 패킷의 사본을 생성하여 함께 송신한다.
중복: 동일 메시지 재전송
duplicate는 패킷만 복제한다. 응답을 수신하지 못하여 재전송하는 경우와 같이 메시지 단위로 발생하는 중복은, 식별자가 같은 요청을 두 번 전송하여 재현한다.
for i in 1 2; do
curl -s -X POST http://127.0.0.1:9000/orders \
-H 'Content-Type: application/json' \
-d '{"messageId": "m-1001", "qty": 3}'
done
확인 항목
| 주입 | 확인 사항 |
|---|---|
| 단절 | timeout이 발생하는지, 해제 후 자동으로 재연결되는지 |
| 지연 | timeout보다 늦게 도착한 응답을 어떻게 처리하는지 |
| 손실 | 재전송으로 최종 전달되는지 |
| 중복 | 동일 메시지가 한 번만 반영되는지 |