CircuitBreaker 는 쉽게 말해 분산 시스템에서 서비스 간 통신의 안정성을 높이기 위한 디자인 패턴입니다.
마이크로서비스 아키텍처가 널리 사용되는 현대의 시스템 환경에서, 서비스 간 의존성으로 인한 문제가 발생할 수 있습니다.
예를 들어, Payment Server 가 Bank Server 에 요청을 보내지만 Bank Server 에 문제가 발생하여 정상적은 응답을 받기 어려운 상황이라 가정해보겠습니다.
이 경우 Payment Server 는 응답을 받지 못하고, 이를 해결하기 위해 재시도(Retry) 메커니즘을 사용할 수 있습니다. Payment Server 는 정상적인 응답을 받을 때까지 장시간 대기하며 계속해서 요청을 보낼 수 있습니다. 그러나 이러한 행동은 오히려 Bank Server 의 부하를 가중시키고, 문제를 더욱 심화시킬 수 있습니다. Bank Server 는 쌓이는 요청을 제대로 처리하지 못한 채 과부하 상태에 빠지게 되어, 결과적으로 문제의 근본적인 해결이 더욱 어려워집니다.
이러한 상황은 DB, Redis, Kafka 와 같은 외부 시스템과의 통신에서도 발생할 수 있습니다. 이들 외부 시스템에 문제가 발생했을 때, 지속적인 요청은 시스템의 회복을 방해할 수 있습니다.
이러한 문제를 해결하기 위해 CircuitBreaker Pattern 이 사용됩니다.
Resilience4j CircuitBreaker 의 컨셉을 참고했습니다.
sliding window
상태 판단을 위한 정보(지표) 수집 방식으로 sliding window 를 사용합니다. 구체적으론 두 방식으로 나뉩니다.
Count-based sliding window :
최근 호출된 N 개의 호출 결과를 집계하여 상태를 판단합니다.
순환 배열로 구현되며 새로운 결과가 추가될 때마다 총 집계를 최신화합니다.
스냅샷 검색 시간은 O(1)로 일정하며 메모리 사용량은 O(N) 입니다.
Time-based sliding window :
특정 시간 범위 내의 호출 결과를 집계하여 상태를 판단합니다.
N 개의 부분 집계(버킷)로 구성된 순환 배열로 구현되며 각 버킷은 1초 동안의 모든 호출 결과를 집계합니다.
가장 오래된 버킷이 제거될 때, 해당 버킷의 부분 집계를 총 집계에서 뺍니다(Subtract-on-Evict).
스냅샷 검색 시간은 O(1)로 일정하며, 메모리 사용량은 O(N)입니다.
Failure rate and slow call rate thresholds
상태 판단 근거와 관련된 내용입니다.
이 상태는 failure rate 가 configurable threshold(failureRateThreshold) 값보다 크거나 같을 때 CLOSED 에서 OPEN 으로 변경합니다. (설정한 실패율 값 이상의 실패율이 측정되면 CircuitBreaker 가 발동됩니다. 상태 OPEN)
기본적으로 대부분의 예외는 실패로 다루며 제외대상을 정할 수도 있습니다.
실패율 말고도 slow call (느린 응답) 이 configurable threshold(callRateThreshold) 값보다 크거나 같을 때 CLOSED 에서 OPEN 으로 변경합니다.
따라서 sliding window 자료구조엔 실패한 호출 수, 느린 호출 수, 총 호출 수, 총 호출 시간 같은 값들을 저장해야합니다.
(원문 : A partial aggregation consists of 3 integers in order to count the number of failed calls, the number of slow calls and total number of calls. And one long which stores total duration of all calls.)
이렇게 OPEN 상태가 된 경우 대기시간이 지난 뒤 HALF_OPEN 상태가 되어 일부 요청을 허용한 뒤 총 집계를 비교하여 Threshold 보다 적어진다면 CLOSED 상태로 변경됩니다.
Netflix 에서 공개한 Latency, Fault Tolerance(내성) 문제를 해결하기 위한 오픈소스 라이브러리.
현재는 추가적인 개발이 없으며 resilience4j 를 사용하길 권장하고 있습니다. 하지만 Hystrix wiki 에서 제공하는 flow chart 가 좋아보여 가져왔습니다.

자세한 사용 정보는 다음 글을 참고해주세요.
G마켓 테크 블로그
Latency, Fault Tolerance 를 위한 오픈소스 라이브러리입니다. (최신 Release, on Jun 29, 2023)
CircuitBreaker 뿐만 아니라 Bulkhead, Ratelimiter 같은 다양한 기능들을 제공합니다.
세부적인 동작방식은 위쪽 메커니즘 부분에서 나왔지만 Resilience4j 에선 OPEN, CLOSED, HALF_OPEN 상태 말고도 DISABLED, FORCED_OPEN 이란 추가 상태가 존재합니다.
DISABLED : 모든 요청을 허용합니다.FORCED_OPEN : 모든 요청을 거부합니다.CircuitBreaker 를 초기화해야합니다.Resilience4j 의 CircuitBreaker 가 어떻게 thread-safe 를 유지하는지는 공식문서를 참고해주세요.
사용 정보는 다음 글을 참고해주세요.
올리브영 테크 블로그
분산환경에서 취약한 Latency, Fault 문제를 해결하는 방식은 CircuitBreaker 뿐만 아니라 Bulkhead, Ratelimiter, Retry, Fallback 같은 개념들이 있습니다. 이러한 개념들도 조금씩 정리해나가면 좋을 것 같습니다.
참고한 자료
https://github.com/Netflix/Hystrix/wiki/
https://resilience4j.readme.io/docs/circuitbreaker
https://dip-mazumder.medium.com/best-practices-for-error-handling-a-guide-to-circuit-breaker-patterns-41d45ffc02ac
https://dev.gmarket.com/40