SCG) CircuitBreaker resilience4j

박우영·2023년 6월 19일
0

자바/코틀린/스프링

목록 보기
29/35

CircuitBreaker 란?

먼저 Circuit Breaker 란 회로차단을 뜻하는데 회로 차단기의 개념은 호출이 실패하거나 시간 초과될 수 있다고 알려진 경우 마이크로 서비스에 대한 호출을 방지하는 것입니다. 이는 클라이언트가 실패할 가능성이 있는 요청을 처리하는 데 소중한 리소스를 낭비하지 않도록 하기 위한 것입니다. 이 개념을 사용하면 서버에 복구할 여유 시간을 줄 수 있습니다.

다음과 같은 상태들이 있다.

  • Closed: 모든 것이 정상일 때. 초기에 close 상태

  • Open: 정해진 설정에 미치치 못할때, 이 상태에서는 다른 마이크로 서비스에 대한 요청이 실행되지 않으며 가능한 경우 빠른 페일백 또는 폴백이 수행됩니다. 이 상태가 특정 시간 제한을 지나면 자동으로 또는 특정 기준에 따라 Half-Open 상태로 돌아갑니다.

  • HalfOpen: 호출하는 마이크로 서비스가 정상적으로 작동하는지 확인하기 위해 여러 요청이 실행됩니다. 성공하면 상태가 닫힘 상태로 돌아갑니다. 그러나 여전히 실패하면 Open 상태로 돌아갑니다.


Gateway에 적용하기

gateway에 circuit breaker 를 적용해보겠습니다.

먼저 의존성을 추가해줍니다.

build.gradle

implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j'

Bean 등록

@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에 등록해줍니다.

application.yml

...
        - 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 # 요청 시간 제한

fallback Controller

@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
  • -c : 한 번에 수행할 여러 요청 수
  • -n : 수행 요청 수

다음과 같이 10개의 요청에 정상적으로 응답이 되는걸 확인 했습니다.

만약 요청을 더 늘려 100개가 된다면 어떻게 될까요???

이미 circuitbreaker 로 설정을 해두었기때문에 실패하더라도 fallback 요청이 올거고 실질적인 요청처리는 문제가 없이 진행되는걸 확인 할 수있습니다.

대신 Circuitbreaker를 grafana 등과 연동하여 open 된건 없는지 확인 하는 apm 시스템을 구축을 해야겠네요

0개의 댓글