- Published on
서킷브레이커란?
- Authors
- Name
- zkrp
도서관 프로젝트의 외부 API 안정성 문제와 서킷 브레이커
도서관 프로젝트를 진행하면서, 여러 기관의 도서 데이터를 가져오기 위해 외부 API를 호출해야 하는 상황이 많았습니다.
그런데 이런 외부 API 호출은 항상 실패 가능성을 안고 있습니다.
예를 들어, 호출이 실패하거나 응답이 지연되면 요청 쓰레드가 타임아웃 될 때까지 대기하게 됩니다.
이 과정에서 쓰레드 풀이나 DB 커넥션 풀이 점점 고갈되고, 메모리 사용량이 늘어나면서 결국에는 시스템 전체 리소스 부족으로 이어질 수 있습니다.
더 큰 문제는 이런 장애가 다른 서비스로 전파되어, 전체 서비스의 성능 저하나 장애 확산으로 번질 수 있다는 점입니다.
또한 이미 장애가 발생한 외부 서버에 계속 요청을 보내는 경우,
그 서버는 회복되기도 전에 다시 부하를 받아 복구가 더욱 어려워지는 악순환이 발생합니다.
따라서 이러한 상황을 방지하기 위해서는, 장애가 발생한 외부 서비스를 탐지하고 일정 시간 동안 요청을 차단하는 메커니즘이 필요합니다.
이 문제를 해결하기 위한 대표적인 설계 패턴이 바로 서킷 브레이커(Circuit Breaker) 입니다.
1. 서킷 브레이커란?
서킷 브레이커는 연동 시 이상을 감지하고, 이상이 발생하면 연동을 차단하고,
이후에 이상이 회복되면 자동으로 다시 연동하기 위한 기술입니다.
즉, 외부 API 통신 중 장애가 발생했을 때 장애 전파를 막고 서비스 안정성을 유지하는 보호 장치의 역할을 합니다.
서킷 브레이커는 3가지 보통 상태(CLOSED, OPEN, HALF_OPEN)와
2가지 특별한 상태(DISABLED, FORCED_OPEN)을 가집니다.
2. 서킷 브레이커의 상태
CLOSED
요청이 정상적으로 처리되고 응답을 받는 상태입니다.
실패율이 임계치 미만이면 계속 CLOSED를 유지합니다.
OPEN
일정 비율 이상 실패 시 요청을 차단하고, 일정 시간 동안 호출이 불가합니다.
HALF_OPEN
일정 시간이 지나면 일부 요청만 허용하여 시스템이 회복되었는지 확인합니다.
DISABLED
서킷 브레이커 기능 자체가 꺼져 있으며, 모든 요청을 통과시킵니다.
FORCED_OPEN
관리자가 임의로 OPEN 상태를 유지시켜 항상 요청을 거부합니다.
3. 상태 전이와 슬라이딩 윈도
서킷 브레이커는 슬라이딩 윈도(Sliding Window) 를 사용하여 상태 변화 여부를 결정합니다.
- 횟수 기반 (COUNT_BASED)
- 시간 기반 (TIME_BASED)
슬라이딩 윈도 안에서 정해진 실패 확률이 임계치를 초과하면 상태를 OPEN으로 변경합니다.
- OPEN 상태에서는 시스템 호출을 시도하지 않고, 바로 예외를 발생시키거나 Fallback 동작을 수행합니다.
- 설정된 시간이 지나면 HALF_OPEN으로 전이되어 정상화 여부를 확인합니다.
- 정상화되면 CLOSED로 돌아가고,
그렇지 않으면 다시 OPEN 상태로 복귀합니다.
4. Fallback (폴백)
서비스를 차단한 경우 예외를 발생시키는 대신, 대비책(Fallback) 을 제공하거나
미리 정의된 동작을 수행할 수 있습니다.
예를 들어, Circuit Breaker가 OPEN 상태일 때
사용자 요청을 에러로 응답하지 않고 대체 응답을 제공합니다.
- 실제 서비스 호출 대신 대체 로직 또는 캐시된 응답을 반환
- 사용자 경험 저하를 최소화
5. 예시 시나리오 - 결제 서비스
상황:
결제 서비스가 외부 카드사 API와 연동 중 장애 발생
시나리오 흐름:
- 실패율이 50% 이상 감지 → Circuit Breaker OPEN
- 이후 30초간 모든 결제 요청 차단 → Fallback으로 “결제 지연 안내” 제공
- 30초 후 일부 트래픽으로 재시도
- 정상 응답 시 → CLOSED 복귀
- 여전히 실패 → 다시 OPEN 유지
6. 마무리
이번 글에서는 서킷 브레이커의 기본 개념과 동작 원리를 살펴봤습니다.
다음 글에서는 도서관 프로젝트에서 실제로 Resilience4j를 사용해 Circuit Breaker를 구현한 사례를 다룰 예정입니다.