먼저 Circuit Breaker 란 회로차단을 뜻하는데 회로 차단기의 개념은 호출이 실패하거나 시간 초과될 수 있다고 알려진 경우 마이크로 서비스에 대한 호출을 방지하는 것입니다. 이는 클라이언트가 실패할 가능성이 있는 요청을 처리하는 데 소중한 리소스를 낭비하지 않도록 하기 위한 것입니다. 이 개념을 사용하면 서버에 복구할 여유 시간을 줄 수 있습니다.
다음과 같은 상태들이 있다.
Closed: 모든 것이 정상일 때. 초기에 close 상태
Open: 정해진 설정에 미치치 못할때, 이 상태에서는 다른 마이크로 서비스에 대한 요청이 실행되지 않으며 가능한 경우 빠른 페일백 또는 폴백이 수행됩니다. 이 상태가 특정 시간 제한을 지나면 자동으로 또는 특정 기준에 따라 Half-Open 상태로 돌아갑니다.
HalfOpen: 호출하는 마이크로 서비스가 정상적으로 작동하는지 확인하기 위해 여러 요청이 실행됩니다. 성공하면 상태가 닫힘 상태로 돌아갑니다. 그러나 여전히 실패하면 Open 상태로 돌아갑니다.
gateway에 circuit breaker 를 적용해보겠습니다.
먼저 의존성을 추가해줍니다.
implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j'
@Bean
public Customizer<ReactiveResilience4JCircuitBreakerFactory> defaultCustomizer() {
return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
.circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
.timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build()).build());
}
custom 한 resilience4 설정을 bean에 등록해줍니다.
...
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/fallback
resilience4j:
circuitbreaker:
instances:
myCircuitBreaker:
sliding-window-size: 10 # 서킷브레이커가 마지막 10개 요청을 고려
permitted-number-of-calls-in-half-open-state: 5 # 반절
failure-rate-threshold: 50 # 그중 50%가 실패하면 open
wait-duration-in-open-state: 10000 # 10초동안 open
register-health-indicator: true
timelimiter:
instances:
myCircuitBreaker:
timeout-duration: 3s # 요청 시간 제한
@RestController
public class FallbackController {
private static final Logger log = LoggerFactory.getLogger(FallbackController.class);
@GetMapping("/fallback")
public Flux<Void> fallback() {
log.info("Fallback");
return Flux.empty();
}
}
SCG는 비동기 방식으로 처리하기때문에 이를 위해 Flux로 빈 Flux.empty 를 발송합니다.
이렇게 설정하면 잘 못된 요청에는 fallback 이 실행됩니다.
사진은 baeker-service 라는 내용이없기때문입니다.
이렇게하면 요청하는 쪽에 error message의 노출을 없앨 수 있고, 회로를 차단 할 수있습니다.
loadbalance 경로를 제대로 설정하면
안에 실 데이터가 없어 빈 값이 출력되지만 성공 되는걸 확인 할 수있습니다.
테스트는 저는 mac을 사용하기때문에 별다른 설정없이 테스트 할 수있게 AB(Apache HTTP server benchmarking tool) 를 사용 하였습니다.
ab -n 10 -c 10 경로 /api/studyrule/v1/search
다음과 같이 10개의 요청에 정상적으로 응답이 되는걸 확인 했습니다.
만약 요청을 더 늘려 100개가 된다면 어떻게 될까요???
이미 circuitbreaker 로 설정을 해두었기때문에 실패하더라도 fallback 요청이 올거고 실질적인 요청처리는 문제가 없이 진행되는걸 확인 할 수있습니다.
대신 Circuitbreaker를 grafana 등과 연동하여 open 된건 없는지 확인 하는 apm 시스템을 구축을 해야겠네요