마이크로서비스(MSA)나 분산 환경에서 장애 전파를 막고, 빠른 예외 처리(fail-fast)를 제공하기 위해 널리 사용되는 서킷 브레이커(Circuit Breaker) 디자인 패턴을 정리해 보았습니다.
서킷 브레이커는 전기 회로 차단기(Circuit Breaker)의 개념을 서비스 간 통신에 적용한 디자인 패턴입니다.
어떤 외부 API나 서비스가 장애(오류가 연속 발생하거나 응답 시간이 지나치게 긴 경우 등)를 일으키면, 계속해서 재시도하기보다는 일정 조건이 충족될 때까지 해당 호출을 빠르게 차단합니다.
이를 통해,
이 패턴은 특히 마이크로서비스 아키텍처나 분산 환경에서 자주 사용되는 패턴입니다.
오류(또는 타임아웃) 임계치 기준
Open 상태 유지 시간(Wait Duration in Open State)
Half-Open 상태에서의 재시도 횟수 (Permitted Number of Calls in Half-Open State)
폴백(Fallback) 로직
모니터링 및 알림
자바/스프링 부트 환경에서 서킷 브레이커 패턴을 구현할 때 대표적으로 사용하는 라이브러리가 Resilience4j입니다.
CircuitBreaker
모듈 외에도 Bulkhead, RateLimiter, Retry 등 다양한 내결함성(Resilience) 패턴을 지원합니다.
dependencies {
implementation 'io.github.resilience4j:resilience4j-spring-boot2:1.7.0'
// 버전은 상황에 맞게 최신으로 조정
}
resilience4j:
circuitbreaker:
configs:
default:
registerHealthIndicator: true
slidingWindowSize: 10 # 오류율 계산에 사용되는 호출 수
permittedNumberOfCallsInHalfOpenState: 3
minimumNumberOfCalls: 5 # 오류율 계산에 필요한 최소 호출 수
failureRateThreshold: 50 # 오류율이 50% 이상이면 Open 상태로 전환
waitDurationInOpenState: 10s # Open 상태 유지 시간
automaticTransitionFromOpenToHalfOpenEnabled: true
# 그 외 timeoutDuration, slowCallRateThreshold 등 다양한 설정 가능
instances:
myServiceCircuitBreaker:
baseConfig: default # 공통 설정 재사용
# 인스턴스별로 다르게 지정할 수도 있음
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
@Service
public class MyService {
// name에는 위에서 설정한 'myServiceCircuitBreaker' 또는 'default' 등 사용
@CircuitBreaker(name = "myServiceCircuitBreaker", fallbackMethod = "fallbackForCallExternalService")
public String callExternalService() {
// 외부 API 호출 로직
// 예: REST API 클라이언트 사용, FeignClient, WebClient 등
// 여기서 장애가 연속 발생하면 서킷 브레이커가 개입
return "성공 응답";
}
// fallbackMethod 시그니처는 원 메서드와 동일하거나, 마지막 인자로 Throwable을 받을 수 있음.
public String fallbackForCallExternalService(Throwable t) {
// 장애 발생 시 대신 리턴할 값을 정의하거나, 캐시에서 읽어오기 등 대체 로직 수행
return "Fallback 응답: 외부 서비스 장애로 인한 대체 응답입니다.";
}
}
위의 예시처럼 애노테이션과 YAML 파일 설정만으로 서킷 브레이커가 동작합니다.
문제가 발생할 경우 callExternalService()에서 예외가 던져지거나 시간이 오래 걸리면, 오류율이 계산되어 임계치에 도달 시 회로가 Open 상태가 됩니다. 이후 일정 시간이 지나면 Half-Open으로 테스트를 진행하고, 성공 시 Closed로 돌아가는 흐름입니다.
Retry
Fallback
Bulkhead
Rate Limiter