본문 바로가기
스터디/Spring

[Springboot] CircuitBreaker 적용방법(2) - 코드 적용

by zoodi 2023. 8. 18.
728x90

목차

     

    지난번 CircuitBreaker 적용방법(1)에 이어서 포스팅하겠습니다.

     

     

    1. CircuitBreaker 코드 적용하기

    방법 1) 코드 적용 방식

    • 연동 로직에 직접 CircuitBreaker를 적용하려면 먼저 적용대상 CircuitBreaker를 CircuitBreakerRegistry를 통해 구해야한다.
    • 연동 로직에 CircuitBreaker를 decorate 하도록 직접 코드를 적용한다.
    • 연동 대상 서버 API 호출 공통 로직에 적용 시 모든 API에 동일한 설정 적용이 가능하다.
    • https://resilience4j.readme.io/docs/examples

    1) Create a CircuitBreakerRegistry

    // Create a custom configuration for a CircuitBreaker
    CircuitBreakerConfig defaultCircuitBreakerConfig = CircuitBreakerConfig.custom()
        .failureRateThreshold(50)
        .waitDurationInOpenState(Duration.ofMillis(1000))
        .permittedNumberOfCallsInHalfOpenState(2)
        .slidingWindowSize(2)
        .recordExceptions(IOException.class, TimeoutException.class)
        .ignoreExceptions(BusinessException.class, OtherBusinessException.class)
        .build();
    
    // Create a CircuitBreakerRegistry with a custom global configuration
    CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.of(defaultCircuitBreakerConfig); // default config로 CircuitBreakerRegistry 생성

     

    2) Create a CircuitBreaker

     

    CircuitBreaker circuitBreaker = circuitBreakerRegistry
      .circuitBreaker("name");

     

    3) Recover from an exception
    CircuitBreaker가 failure로 기록하고 난 후 예외 recover 처리진행

    // Given
    CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("testName");
    
    // When I decorate my function and invoke the decorated function
    Supplier<String> checkedSupplier =
      CircuitBreaker.decorateSupplier(circuitBreaker, () -> {
    	//기존 로직 작성
        throw new RuntimeException("BAM!");
      });
    
    //fallback 처리
    Try<String> result = Try.ofSupplier(checkedSupplier)
      .recover(throwable -> "Hello Recovery");
    
    // Then the function should be a success, 
    // because the exception could be recovered
    assertThat(result.isSuccess()).isTrue();
    // and the result must match the result of the recovery function.
    assertThat(result.get()).isEqualTo("Hello Recovery");

     

    반대로 예외 recover 진행 후 CircuitBreaker가 failure로 기록하게하고 싶다면 아래와 같이 수행

     

    Supplier<String> supplier = () -> {
    			//기존 로직 작성
                throw new RuntimeException("BAM!");
            };
    
    //fallback 처리
    Supplier<String> supplierWithRecovery = SupplierUtils
      .recover(supplier, (exception) -> "Hello Recovery");
    
    
    String result = circuitBreaker.executeSupplier(supplierWithRecovery);
    
    assertThat(result).isEqualTo("Hello Recovery");

    방법 2) 어노테이션 방식

    • 연동 API 메소드 각각에 @CircuitBreaker 어노테이션을 적용하는 방식
    • 오류 발생시 호출될 fallback 메소드 지정이 가능하다.
    • 연동 대상 서버 API별 메소드 단위로 다른 설정의 circuitbreaker 적용하기 유용
    • https://resilience4j.readme.io/docs/getting-started-3
     

    Getting Started

    Getting started with resilience4j-spring-boot2 or resilience4j-spring-boot3

    resilience4j.readme.io

    @Service
    @Slf4j
    public class CircuitBreakerService {
    
    	@CircuitBreaker(name = Resilience4jCode.CIRCUIT_TEST, fallbackMethod = "getCircuitBreakerFallback")
    	public String getHello() {
    		runtimeException();
    		return "hello world!";
    	}
    
    	@Retry(name = Resilience4jCode.RETRY_TEST, fallbackMethod = "getRetryFallback")
    	public String getRetry() {
    		log.info("====== getRetry Request !! =======");
    		runtimeException();
    		return "hello world!";
    	}
    
    	private void runtimeException() {
    		throw new RuntimeException("failed");
    	}
    	private String getCircuitBreakerFallback(Throwable t) {
    		return "getCircuitBreakerFallback! exception type: " + t.getClass() + "message: " + t.getMessage();
    	}
    
    	private String getRetryFallback(Throwable t) {
    		return "getRetryFallback! exception type: " + t.getClass() + "message: " + t.getMessage();
    	}
    }

     

    참고: resilience4j grafana: https://resilience4j.readme.io/docs/grafana-1

    728x90

    댓글