LabHub

마이크로서비스 아키텍처 · 회복탄력성(타임아웃·재시도·서킷브레이커) · 실습

서킷 브레이커 구현과 상태 전이 검증

LabHub 에서 이어서 보기

목표

서킷 브레이커를 직접 구현해 CLOSED, OPEN, HALF_OPEN 사이의 전이를 눈으로 확인하고, 무엇을 실패로 셀지의 결정이 왜 가장 중요한지 사고 사례로 체감한다.

왜 중요한가

서킷 브레이커는 장애를 고치는 장치가 아닙니다. 장애가 확실할 때 빠르게 실패해서 호출자의 커넥션 풀이 마르지 않게 지키는 장치입니다. 그래서 성능 지표가 아니라 격리 지표로 평가해야 합니다. 실무에서 서킷이 만드는 사고는 대부분 두 가지입니다. 첫째, 4xx 를 실패로 집계해 정상 트래픽까지 차단하는 것 — 재고 서비스가 특정 상품에 400 을 주기 시작하자 서킷이 열려 정상 상품 조회까지 막힌 사례가 있습니다. 둘째, HALF_OPEN 시험 호출을 1건만 허용해 OPEN 과 HALF_OPEN 을 오가며 플래핑하는 것입니다. 이 실습은 그 두 함정을 각각 한 스텝씩 배정해 직접 만들고 직접 막습니다.

단계

1. /opt/app/flaky.py 를 127.0.0.1:8110 에 띄운다. GET /count 가 지금까지 받은 요청 수를 JSON 으로 준다.
2. /root/cb/breaker.py 를 만들어 /fast 를 3번 호출한다. /root/cb/state.json{"state":"CLOSED", ...} 를 쓴다.
3. /always500 을 5번 호출해 실패율 임계값을 넘긴다. 설정은 윈도우 10, 최소 호출 5, 실패율 50% 이다. state.jsonstateOPEN 이 된다.
4. OPEN 상태에서 10번 더 호출한다. /root/cb/fastfail.txtbefore=<n> after=<n> blocked=10 max_ms=<밀리초> 를 적는다. before 와 after 가 같아야 하고 max_ms 는 50 미만이어야 한다.
5. waitDurationInOpenState 를 3초로 두고 3초 이상 기다린 뒤 한 번 호출한다. state.jsonstateHALF_OPEN 이 된다.
6. HALF_OPEN 에서 /fast 를 3번 성공시켜 CLOSED 로 되돌린다. permitted_in_half_open 값이 3 이상으로 기록되어야 한다.
7. 새 브레이커로 /bad(400)를 10번 호출한다. /root/cb/ignore4xx.jsonstate 는 여전히 CLOSED 이고 failures 는 0 이어야 한다.
8. 전체 시나리오를 한 번에 돌려 /root/cb/transitions.logCLOSED->OPEN, OPEN->HALF_OPEN, HALF_OPEN->CLOSED 세 줄을 이 순서로 남긴다.

참고

단계 8개

  1. 다운스트림과 호출 카운터 준비하기
  2. CLOSED 상태에서 통과시키기
  3. 실패율 임계값으로 OPEN 만들기
  4. OPEN 에서 다운스트림에 가지 않음을 증명하기
  5. 대기 시간 후 HALF_OPEN 으로 전이하기
  6. 시험 호출 성공으로 CLOSED 복귀하기
  7. 4xx 를 실패로 세지 않기
  8. 전이 이력으로 종합 검증하기