Resilience4J - circuit breaker 실습

johaS2·2025년 2월 9일

Resilience4J 란?

Resilience4J 제공 모듈

  • circuit-breaker : 회로 차단기
  • fall-back : 실패시 동작
  • retry : 자동 재시도
  • bulk-head : 동시 실행 제한
  • rate-limiter : 속도(성능) 제한
  • time-limiter : 시간 초과 제한
  • cache : 결과 캐싱

프로젝트 실습 !

  • 구조

    Service2에서 Service1을 호출하는 상황에서 Service2에 circuit을 open할 Resilience4J의 circuit breaker를 적용

  • spring web, lombok, resilience4j 의존성 필수

  • 추가 의존성

implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation 'io.github.resilience4j:resilience4j-all'
  • Controller 생성
@Controller
@ResponseBody
public class MainController {

		private Rest1Comp rest1Comp;

    @Autowired
    public MainController(Rest1Comp rest1Comp) {

        this.rest1Comp = rest1Comp;
    }

    @GetMapping("/")
		public String mainP() {

        return rest1Comp.restTemplate1().getForObject("/data", String.class);
    }
}
  • RestTemplate 생성 : Service2에서 Service1을 호출하도록 설정
@Component
public class Rest1Comp {

    @Bean
    public RestTemplate restTemplate1() {

        return new RestTemplateBuilder().rootUri("http://localhost:9000")
                .build();
    }
  • Service 1 API 서버 구축 (10초간 지연 발생)
    server.port=9000
@Controller
@ResponseBody
public class DataController {

    @GetMapping("/data")
    public String dataP() {

        String nowTime = String.valueOf(LocalDateTime.now());

        try {

            Thread.sleep(10000);
        } catch (InterruptedException e) {

            throw new RuntimeException(e);
        }

        return nowTime;
    }
}
  • Service 2 서버에 circuit breaker 적용

circuit breaker 어노테이션 방식 적용

@CircuitBreaker(name = "특정할이름", fallbackMethod = "실패시수행할메소드이름")
@GetMapping("/")
public String mainP() {

    return rest1Comp.restTemplate1().getForObject("/data", String.class);
}

name에 대한 circuit breaker 설정

resilience4j.circuitbreaker.instances.특정할이름.base-config=설정셋`
  1. 변수에 대한 특정한 이름 설정
resilience4j.circuitbreaker.configs.설정셋.메소드들=값

#예시
resilience4j.circuitbreaker.configs.default.failure-rate-threshold=10
  1. 슬라이딩 윈도우 공통 사항
#실패 및 지연을 체크할 슬라이딩 윈도우 타입
resilience4j.circuitbreaker.configs.default.sliding-window-type=count_based

#슬라이딩 윈도우 크기
resilience4j.circuitbreaker.configs.default.sliding-window-size=5
  1. 실패에 대한 설정
#서킷을 오픈할 실패 비율 (실패 수 / 슬라이딩 윈도우 크기)
resilience4j.circuitbreaker.configs.default.failure-rate-threshold=10

#서킷을 오픈하기 위해 최소 실패 수 (슬라이딩 윈도우를 다 채우지 못했지만 최소값을 설정 가능)
resilience4j.circuitbreaker.configs.default.minimum-number-of-calls=5
  1. 지연에 대한 설정
#서킷을 오픈할 지연 비율 (지연 수 / 슬라이딩 윈도우 크기)
resilience4j.circuitbreaker.configs.default.slow-call-rate-threshold=10

#지연으로 판단할 시간
resilience4j.circuitbreaker.configs.default.slow-call-duration-threshold=3000ms
  1. half open 상태 설정
#half open 상태에서 다른 상태로 전환하기 위한 판단 수
resilience4j.circuitbreaker.configs.default.permitted-number-of-calls-in-half-open-state=10


#half open 상태 유지 시간 (만약 0이면 위에서 설정한 값 만큼 수행 후 다음 상태로 전환)
resilience4j.circuitbreaker.configs.default.max-wait-duration-in-half-open-state=0


#open 상태에서 half open으로 전환까지 기다리는 시간
resilience4j.circuitbreaker.configs.default.wait-duration-in-open-state=600000ms


#open 상태에서 half open 으로 자동 전환 (true시 일정 시간이 지난 후 자동 전환)
resilience4j.circuitbreaker.configs.default.automatic-transition-from-open-to-half-open-enabled=true

#상태 체크 표시 (actuator용)
resilience4j.circuitbreaker.configs.default.register-health-indicator=true
  1. 예외 처리
resilience4j.circuitbreaker.configs.default.ignore-exceptions[0]=java.io.IOException
resilience4j.circuitbreaker.configs.default.ignore-exceptions[1]=java.util.concurrent.TimeoutException
resilience4j.circuitbreaker.configs.default.ignore-exceptions[2]=org.springframework.web.client.HttpServerErrorException
  • fallback 메소드 설정
    Service1이 지연될 경우 Service2에서 fallback 메소드 실행
@CircuitBreaker(name = "특정할이름", fallbackMethod = "실패시수행할메소드이름")
@GetMapping("/")
public String mainP() {

    return rest1Comp.restTemplate1().getForObject("/data", String.class);
}

private String 실패시수행할메소드이름(Throwable throwable) {

    return throwable.getMessage();
}
profile
passionate !!

0개의 댓글