본문 바로가기
MSA

Resilience4j

by xogns93 2024. 12. 13.

Resilience4j란?

 

Resilience4j는 Spring Boot 애플리케이션에서 회복력 있는 마이크로서비스를 구축하기 위해 설계된 경량 라이브러리입니다. Circuit Breaker, Rate Limiter, Retry, Bulkhead, Time Limiter와 같은 주요 패턴을 제공합니다. 각 패턴은 별도로 구현되며, 원하는 모듈만 선택해서 사용할 수 있는 장점이 있습니다.

 

주요 기능

  1. Circuit Breaker (회로 차단기)
    서비스 호출 실패가 반복되면 회로를 열어 추가 실패를 방지하고, 일정 시간이 지나면 재시도를 허용합니다.
  2. Rate Limiter (속도 제한기)
    호출 횟수를 제한하여 서비스 과부하를 방지합니다.
  3. Retry (재시도)
    실패한 요청을 재시도하여 잠재적 네트워크 문제를 해결합니다.
  4. Bulkhead (벌크헤드)
    서비스의 스레드 및 리소스를 분리하여 한 서비스의 장애가 전체 시스템에 영향을 미치지 않도록 합니다.
  5. Time Limiter (시간 제한기)
    호출 시간이 초과되면 타임아웃 처리합니다.

 


1. 회로차단기 (Circuit Breaker)

개념

  • 회로차단기는 연속된 실패를 감지하여 시스템 자원을 보호하기 위해 회로를 열어서 추가적인 요청을 차단합니다.

동작 원리

  1. Closed (닫힘): 서비스가 정상적으로 작동합니다. 실패율이 설정된 임계치를 초과하면 Open 상태로 전환됩니다.
  2. Open (열림): 모든 요청을 차단하며, 바로 실패로 응답합니다. 일정 시간이 지나면 Half-Open 상태로 변경됩니다.
  3. Half-Open (반열림): 일부 요청만 허용하여 서비스가 정상적으로 복구되었는지 확인합니다. 성공하면 Closed 상태로 돌아가고, 실패하면 Open 상태로 전환됩니다.

주요 설정

  • failureRateThreshold: 회로를 열기 위한 실패율 임계치 (기본값: 50%).
  • slidingWindowSize: 실패율을 계산하는 기준이 되는 호출 수.
  • waitDurationInOpenState: Open 상태에서 Half-Open 상태로 전환되기 전 대기 시간.
  • permittedNumberOfCallsInHalfOpenState: Half-Open 상태에서 허용되는 호출 수.

적용 사례

  • 외부 API 호출이 일정 횟수 이상 실패할 때 이를 차단하여 리소스를 보호.

YAML 설정 예시

resilience4j.circuitbreaker.instances.licenseService:
  failureRateThreshold: 50
  sliding-window-size: 100
  waitDurationInOpenState: 10s
  permitted-number-of-calls-in-half-open-state: 10
  recordExceptions:
    - org.springframework.web.client.HttpServerErrorException
    - java.io.IOException

2. 재시도 (Retry)

개념

  • 재시도는 요청이 실패했을 때 지정된 횟수만큼 다시 시도하는 기능입니다.

동작 원리

  1. 요청이 실패할 경우, 정의된 횟수만큼 재시도합니다.
  2. 재시도 간격 또는 대기 시간을 설정할 수 있습니다.
  3. 폴백 메서드를 통해 최종적으로 실패한 경우 대체 동작을 처리할 수 있습니다.

주요 설정

  • max-attempts: 최대 재시도 횟수 (기본값: 3).
  • waitDuration: 각 재시도 사이의 대기 시간.
  • retry-exceptions: 재시도를 트리거하는 예외 목록.

적용 사례

  • 네트워크 연결 문제로 인한 일시적인 실패를 처리.

YAML 설정 예시

resilience4j.retry.instances.retryLicenseService:
  max-attempts: 5
  waitDuration: 1000ms
  retry-exceptions:
    - java.util.concurrent.TimeoutException

코드 예시

@Retry(name = "retryLicenseService", fallbackMethod = "fallbackForRemoteCall")
public String callRemoteService() {
    // 네트워크 호출
}

public String fallbackForRemoteCall(Exception e) {
    return "Fallback response due to: " + e.getMessage();
}

3. 벌크헤드 (Bulkhead)

개념

  • 벌크헤드는 시스템 자원을 분리하여 특정 서비스의 과부하가 다른 서비스에 영향을 미치지 않도록 방지합니다.

방식

  1. 스레드풀 방식: 서비스 요청을 처리하기 위해 별도의 스레드풀을 사용.
  2. 세마포어 방식: 동시 요청의 수를 제한.

주요 설정

  • 스레드풀 방식:
    • max-thread-pool-size: 스레드풀의 최대 크기.
    • core-thread-pool-size: 스레드풀의 기본 크기.
    • queue-capacity: 대기 큐의 크기.
  • 세마포어 방식:
    • max-concurrent-calls: 동시에 처리 가능한 요청 수.

적용 사례

  • 특정 서비스가 과부하 상태가 되더라도 다른 서비스가 정상적으로 작동하도록 분리.

YAML 설정 예시

resilience4j.thread-pool-bulkhead.instances.bulkheadLicenseService:
  max-thread-pool-size: 20
  core-thread-pool-size: 10
  queue-capacity: 10

4. 속도 제한 (Rate Limiter)

개념

  • 단위 시간당 처리할 수 있는 요청의 수를 제한하여 시스템이 과부하 상태에 빠지지 않도록 합니다.

주요 설정

  • limitForPeriod: 단위 시간당 허용되는 요청 수.
  • limitRefreshPeriod: 요청 제한을 초기화하는 주기.
  • timeoutDuration: 초과된 요청이 얼마나 대기할 수 있는지.

적용 사례

  • API 호출을 제한하여 특정 서비스가 과부하 상태에 빠지지 않도록 보호.

YAML 설정 예시

resilience4j.ratelimiter.instances.licenseService:
  limitForPeriod: 5
  limitRefreshPeriod: 5000ms
  timeoutDuration: 1000ms

5. 폴백 (Fallback)

개념

  • 회로차단기와 재시도에서 모두 실패한 경우, 폴백을 통해 대체 동작을 수행합니다.

적용 사례

  • 원격 호출 실패 시 기본값 반환 또는 캐시된 데이터 제공.

코드 예시

@Retry(name = "retryLicenseService", fallbackMethod = "fallbackForRemoteCall")
public String callExternalService() {
    throw new RuntimeException("Service unavailable");
}

public String fallbackForRemoteCall(RuntimeException e) {
    return "Fallback response: " + e.getMessage();
}

6. 캐싱 (Cache)

개념

  • 동일한 요청에 대해 반복적으로 호출하지 않고 결과를 캐싱하여 성능을 최적화합니다.

주요 설정

  • cacheDuration: 캐싱 기간.
  • cacheCapacity: 캐싱할 데이터의 최대 수.

적용 사례

  • 데이터베이스나 원격 API의 빈번한 호출을 줄임.

YAML 설정 예시

resilience4j.cache.instances.cacheService:
  cacheDuration: 10m
  cacheCapacity: 100

정리

  • 회로차단기 (Circuit Breaker): 연속된 실패 시 요청 차단.
  • 재시도 (Retry): 요청 실패 시 재시도.
  • 벌크헤드 (Bulkhead): 자원 분리로 과부하 방지.
  • 속도 제한 (Rate Limiter): 초당 요청 수 제한.
  • 폴백 (Fallback): 최종 실패 시 대체 동작 수행.
  • 캐싱 (Cache): 동일한 요청 결과를 캐싱.

 

Resilience4j YML 설정 분석 (예제 참고)

1. Circuit Breaker

resilience4j.circuitbreaker:
  instances:
    licenseService:
      registerHealthIndicator: true
      sliding-window-size: 100
      permitted-number-of-calls-in-half-open-state: 10
      waitDurationInOpenState: 10s
      failureRateThreshold: 50
      recordExceptions:
        - org.springframework.web.client.HttpServerErrorException
        - java.io.IOException
        - java.util.concurrent.TimeoutException
        - org.springframework.web.client.ResourceAccessException
    organizationService:
      registerHealthIndicator: true
      sliding-window-size: 6
      permitted-number-of-calls-in-half-open-state: 4
      waitDurationInOpenState: 20s
      failureRateThreshold: 60
  • sliding-window-size: 회로 차단기의 슬라이딩 윈도우 크기입니다. 최근 100개의 호출에 대해 성공/실패 비율을 평가합니다.
  • permitted-number-of-calls-in-half-open-state: 반열림(Half-Open) 상태에서 허용되는 호출 수.
  • waitDurationInOpenState: Open 상태가 유지되는 시간 (10초).
  • failureRateThreshold: 실패율 임계값입니다. 예를 들어, 실패율이 50% 이상이면 회로를 엽니다.
  • recordExceptions: 실패로 간주할 예외 목록.

구현 효과:
licenseServiceorganizationService 호출에서 설정된 실패율과 조건에 따라 회로를 열어 서비스의 부하를 줄이고 안정성을 유지합니다.


2. Rate Limiter

resilience4j.ratelimiter:
  instances:
    licenseService:
      limitForPeriod: 5
      limitRefreshPeriod: 5000
      timeoutDuration: 1000ms
  • limitForPeriod: 제한된 시간 동안 허용되는 최대 호출 수 (5개).
  • limitRefreshPeriod: 호출 제한이 초기화되는 주기 (5초).
  • timeoutDuration: 제한 초과 시 대기하는 시간 (1초).

구현 효과:
licenseService 호출이 과도하게 이루어지지 않도록 제한합니다. 5초마다 최대 5개의 호출만 허용합니다.


3. Retry

resilience4j.retry:
  instances:
    retryLicenseService:
      max-attempts: 5
      waitDuration: 10000
      retry-exceptions:
        - java.util.concurrent.TimeoutException
  • max-attempts: 최대 재시도 횟수 (5회).
  • waitDuration: 재시도 간 대기 시간 (10초).
  • retry-exceptions: 특정 예외 발생 시에만 재시도를 수행합니다.

구현 효과:
타임아웃 예외 발생 시 요청을 최대 5회까지 재시도하여, 일시적인 네트워크 장애를 복구합니다.


4. Bulkhead (Thread Pool Bulkhead)

resilience4j:
  thread-pool-bulkhead:
    instances:
      bulkheadLicenseService:
        max-thread-pool-size: 20
        core-thread-pool-size: 10
        queue-capacity: 10
  • max-thread-pool-size: 스레드풀의 최대 크기 (20).
  • core-thread-pool-size: 기본적으로 유지되는 스레드 수 (10).
  • queue-capacity: 대기 요청 큐의 최대 크기 (10).

구현 효과:
licenseService 호출에 대한 병렬 스레드 수를 제한하여, 시스템 과부하를 방지합니다.


Resilience4j의 적용 방법

  1. YAML 설정: 위와 같은 YML 파일에서 원하는 모듈을 설정합니다.
  2. 의존성 추가:
  3. <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-spring-boot2</artifactId> </dependency>
  4. 애노테이션 적용:
    • Circuit Breaker:
    • @CircuitBreaker(name = "licenseService", fallbackMethod = "fallbackMethod") public String licenseService() { // 비즈니스 로직 }
    • Retry:
    • @Retry(name = "retryLicenseService") public String retryMethod() { // 재시도할 메서드 }
  5. 로그 모니터링: Actuator를 통해 회로 상태를 모니터링할 수 있습니다.

'MSA' 카테고리의 다른 글

Netflix Zuul ( API 게이트웨이 )  (1) 2024.12.16
폴백(Fallback)  (0) 2024.12.13
allow-bean-definition-overriding  (1) 2024.12.11
@ConfigurationProperties  (0) 2024.12.11
리프레시 스코프(Refresh Scope)  (0) 2024.12.11