--- title: concept / Circuit Breaker source_type: llm-generated status: reviewed confidence: high tags: [concept, ca-tmpl, architecture, spring-boot, circuit-breaker] related_projects: [ca-tmpl] last_reviewed: 2026-06-15 --- # concept / Circuit Breaker ## Summary 외부 서비스(의존성) 호출의 실패율을 감시하여, 실패율이 임계치를 초과하면 연동을 즉시 차단(OPEN)함으로써 시스템 전체로 장애가 전파되는 것을 차단하고 빠른 실패(Fail-Fast)를 유도하는 리질리언스 패턴. ## Standard (공식 정의) 서킷 브레이커는 크게 세 가지 상태를 가지며, 유한 상태 머신(FSM)으로 동작한다. - **CLOSED**: 정상 상태. 모든 요청을 외부 서비스로 통과시킨다. 최근 N개 호출(Count-Based) 또는 T초간 호출(Time-Based)의 실패율을 측정한다. - **OPEN**: 차단 상태. 외부 서비스로 요청을 보내지 않고 즉시 예외(CallNotPermittedException)를 던져 빠른 실패를 유도한다. 특정 대기 시간(Wait Duration)이 지나면 HALF_OPEN 상태로 전이한다. - **HALF_OPEN**: 감시 통과 상태. 설정된 횟수만큼 제한된 요청을 외부로 전송하여 성공 여부를 측정한다. 만약 재발한 실패율이 임계치 이하면 CLOSED로 복귀하고, 또다시 임계치를 초과하면 OPEN으로 회귀한다. ## 한계 / 주의점 - **지표 누수(Metric Cardinality Explosion)**: Resilience4j 등 라이브러리는 기본적으로 매우 세부적인 게이지와 카운터 지표(예: slow call rate, buffered calls 등)를 대량 방출한다. 이를 모니터링 시스템(Prometheus 등)에 그대로 전송하면 시계열 데이터 개수가 급증하여 저장소 과부하를 초래한다. 실무에서는 엄격히 합의된 저카디널리티(low-cardinality) 필수 지표만 필터링하여 통과시켜야 한다. - **Retry와의 충돌**: 서킷 브레이커와 리트라이를 무작정 함께 배치하면, 하나의 외부 요청 실패가 리트라이 3회로 증폭되어 서킷 브레이커가 오작동하거나 윈도우 슬라이딩의 실패율이 왜곡될 수 있다. ## Project Application - [[wiki/explainer/adapter-outbound.md]] - `OutboundHttpResilience`에서 각 의존성별로 독립된 `CircuitBreaker`와 `Retry`를 구성함. - `OutboundHttpResilienceConfig`에서 D3/D4 가이드라인을 강제하여: - 리질리언스를 켤 때 지표 수집기(`MeterRegistry`)가 없으면 애플리케이션 기동을 에러로 즉시 차단(Activation Guard). - Prometheus 지표 수집을 위해 `resilience4j.retry.calls`, `resilience4j.circuitbreaker.calls`, `resilience4j.circuitbreaker.state` 딱 3가지 필수 지표만 허용하고 나머지는 강제 차단(Deny Filter)함. - 가시성을 높이기 위해 벤더 사양의 태그를 `outcome` (SUCCESS/FAILURE) 및 대문자 `state` (CLOSED, OPEN, HALF_OPEN)로 정형화(Metric Normalisation)하여 바인딩함. ## Claim-backed Knowledge | Knowledge Point | Supporting Claims | Confidence | Notes | |---|---|---|---| | 서킷 브레이커의 표준 구조 및 Resilience4j 사양 | `raw/official-docs/outbound-resilience4j-vs-spring-retry.md` | `high` | Resilience4j 공식 사양 | | 지표 카디널리티 폭발 문제 및 모니터링 필터링 규칙 | `raw/official-docs/resilience4j-micrometer-module.md` | `high` | Micrometer 통합 모범 사례 | ## 내가 설명할 수 있어야 하는 것 - 서킷 브레이커의 세 가지 상태와 그 전이 조건은 무엇인가? - 왜 리트라이와 서킷 브레이커를 결합할 때 데코레이팅 순서가 중요한가? (CB가 Retry의 바깥쪽에 위치해야 각 재시도 실패가 개별적으로 서킷 실패율에 반영되지 않고 전체 실패로 깔끔하게 묶이거나, 혹은 구조에 따라 왜곡이 발생할 수 있음을 알아야 한다.) - 카디널리티 폭발(Metric Cardinality Explosion)이란 무엇이며, 우리 프로젝트는 이를 어떻게 대처했는가? ## Interview Questions - 마이크로서비스 환경에서 서킷 브레이커의 필요성과 작동 방식(FSM)을 설명하십시오. - 서킷 브레이커를 적용한 후 모니터링 시스템의 시계열 부하(Cardinality)가 급증하는 문제를 해결하기 위해 구체적으로 어떤 조치를 취할 수 있습니까? ## Do Not Overclaim - "서킷 브레이커가 동작하면 분산 시스템의 네트워크 순단에 대비해 무조건 가용성이 높아진다"고 단정하면 안 된다. 서킷이 열려 있는(OPEN) 동안은 정상 요청조차 즉시 거절되므로, 가용성은 일시적으로 0이 된다. 서킷 브레이커의 목표는 가용성 향상뿐 아니라 **호출 측의 스레드 고갈 방지 및 업스트림 서버 보호**임을 명시해야 한다. ## Sources - [Resilience4j CircuitBreaker Core Guide](https://resilience4j.readme.io/docs/circuitbreaker) - [[raw/official-docs/outbound-resilience4j-vs-spring-retry.md]] - [[raw/official-docs/resilience4j-micrometer-module.md]]