dependencies {
implementation 'io.github.resilience4j:resilience4j-spring-boot3:2.2.0'
implementation 'org.springframework.boot:spring-boot-starter-aop'
}
다음 io.github.resilience4j dependency를 사용하려면 springboot 3 버전과 aop 를 추가해줘야 한다.
resilience4j:
circuitbreaker:
configs:
default: # 기본 구성 이름
registerHealthIndicator: true # 애플리케이션의 헬스 체크에 서킷 브레이커 상태를 추가하여 모니터링 가능
# 서킷 브레이커가 동작할 때 사용할 슬라이딩 윈도우의 타입을 설정
# COUNT_BASED: 마지막 N번의 호출 결과를 기반으로 상태를 결정
# TIME_BASED: 마지막 N초 동안의 호출 결과를 기반으로 상태를 결정
slidingWindowType: COUNT_BASED # 슬라이딩 윈도우의 타입을 호출 수 기반(COUNT_BASED)으로 설정
# 슬라이딩 윈도우의 크기를 설정
# COUNT_BASED일 경우: 최근 N번의 호출을 저장
# TIME_BASED일 경우: 최근 N초 동안의 호출을 저장
slidingWindowSize: 5 # 슬라이딩 윈도우의 크기를 5번의 호출로 설정
minimumNumberOfCalls: 5 # 서킷 브레이커가 동작하기 위해 필요한 최소한의 호출 수를 5로 설정
slowCallRateThreshold: 100 # 느린 호출의 비율이 이 임계값(100%)을 초과하면 서킷 브레이커가 동작
slowCallDurationThreshold: 60000 # 느린 호출의 기준 시간(밀리초)으로, 60초 이상 걸리면 느린 호출로 간주
failureRateThreshold: 50 # 실패율이 이 임계값(50%)을 초과하면 서킷 브레이커가 동작
permittedNumberOfCallsInHalfOpenState: 3 # 서킷 브레이커가 Half-open 상태에서 허용하는 최대 호출 수를 3으로 설정
# 서킷 브레이커가 Open 상태에서 Half-open 상태로 전환되기 전에 기다리는 시간
waitDurationInOpenState: 20s # Open 상태에서 Half-open 상태로 전환되기 전에 대기하는 시간을 20초로 설정
위 처럼 yml 파일에 관련 설정을 추가할 수 있는데 https://resilience4j.readme.io/docs/getting-started-3 에서 제공하는 따라하면서 만들기 같은 튜토리얼을 제공하고있다. 이 설정은 실무에서는 이미 작성되어있을 경우가 대다수이며, 팀원들과의 회의를 통해 정할 부분이라 현재는 어떤게 뭔지 알고만 가는 느낌으로 정리했다.
@Service
public class MyService {
@CircuitBreaker(name = "myService", fallbackMethod = "fallbackMethod")
public String myMethod() {
// 외부 서비스 호출
return externalService.call();
}
public String fallbackMethod(Throwable t) {
return "Fallback response";
}
}
다음처럼 @CircuitBreaker 어노테이션에서 fallbackMethod 를 지정해주면 해당 메서드에서 exception이 터질 때 자동으로 fallbackMethod가 실행되게 된다.
fallbackMethod 안에는 개발자에게 email, slack, sns 같은 알림을 통해 전송하고, 사용자에게 사용이 불가능함을 알리거나 여러 추가적인 로직을 구성할 수 있다.
dependencies {
implementation 'io.github.resilience4j:resilience4j-micrometer'
implementation 'io.micrometer:micrometer-registry-prometheus'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
}
위의 설정을 통해 prometheus 로 데이터를 수집하고 micrometer로 모니터링 할 수 있다. 실제로는 grafana로 확인한다.
management:
endpoints:
web:
exposure:
include: prometheus
prometheus:
metrics:
export:
enabled: true
spring actuactor 와 prometheus 를 같이 사용하면 prometheus가 /actuactor 페이지를 보고 메트릭을 수집해서 정리한다.

다음처럼 확인할 수 있는데, 눈으로 확인하기는 어렵기 때문에 grafana 같은 대시보드를 주로 활용하는 것 같다. 잘 확인해보면 circuitbreaker 에 대한 정보도 확인할 수 있다.

productId 가 111 일 때, exception을 터트리고 fallbackMethod 가 호출하는 flow로 이루어져 있다.

설정한 실패율 50% 넘어서 Current failure rate : 60.0 이 되는 순간 CircuitBreaker의 상태가 OPEN 으로 변해 동작하는 상태가 된다.

그 후 모든 요청에 대해서 실패처리를 해버리고 HALF_OPEN 상태로 변경되는데, 여기서 또 exception이 터진다면 OPEN 상태로 가고, 정상적으로 처리가 가능하다면 CLOSED 상태로 CiruitBreaker가 동작하지 않는 상태가 된다.
만약 5개의 외부서비스를 호출하는 메서드에서 오류가 터진다고 했을 때, 서킷 브레이커가 없다면 오류가 계속 전파되어 어디서 시작된 오류인지 확인하기 어려울 수 있다.
하지만, 서킷 브레이커가 fail-fast 함으로써 장애가 나더라도 전파를 최소화하고, 오류를 빠르게 받아올 수 있다는 것을 확인했다.
MSA 아키텍처에서는 더더욱 오류 전파를 최소화 해야하기에 중요한 기술이다.