resilience4j 공식 레퍼런스를 한글로 번역한 문서입니다.
전체 목차는 여기에 있습니다.
목차
- Introduction
- Setup
- Usage
- Usage - Suspending Functions
- Usage - Flow
- Bulkhead
- CircuitBreaker
- Rate Limiter
- Retry
- Time Limiter
Introduction
코틀린 코루틴 통합 모듈. 이 모듈은 코루틴 리액티브 프리미티브 Flow를 위한 커스텀 연산자뿐만 아니라 suspend
함수를 실행하고 데코레이트하기 위한 익스텐션을 추가로 제공한다.
코틀린 suspend 함수를 받는 익스텐션 함수는 RateLimiter, Retry, CircuitBreaker, TimeLimiter, 세마포 기반 Bulkhead에 제공된다. 현재는 ThreadPoolBulkhead나 Cache를 위한 익스텐션은 제공하지 않는다.
Flow의 경우 RateLimiter, Retry, CircuitBreaker, TimeLimiter, 세마포 기반 Bulkhead를 위한 연산자를 제공한다. 현재는 ThreadPoolBulkhead나 Cache를 위한 익스텐션은 제공하지 않는다.
Setup
Resilience4j의 코틀린 모듈을 필요한 핵심 모듈과 함께 compile 의존성에 추가해라:
repositories {
jCenter()
}
dependencies {
compile "io.github.resilience4j:resilience4j-kotlin:${resilience4jVersion}"
// also have a dependency on the core module(s) needed - for example, retry:
compile "io.github.resilience4j:resilience4j-retry:${resilience4jVersion}"
}
Usage
CircuitBreaker
, RateLimiter
, Retry
, TimeLimiter
에는 익스텐션 함수가 두 개씩 선언돼 있다. 하나는 suspend 함수를 실행하고, 다른 하나는 suspend 함수를 데코레이팅한다.
Usage - Suspending Functions
CircuitBreaker
, RateLimiter
, Retry
, TimeLimiter
에는 익스텐션 함수가 두 개씩 선언돼 있다. 하나는 suspend 함수를 실행하고, 다른 하나는 suspend 함수를 데코레이팅한다.
val circuitBreaker = CircuitBreaker.ofDefaults()
val result = circuitBreaker.executeSuspendFunction {
// call suspending functions here
}
val function = circuitBreaker.decorateSuspendFunction {
// call suspending functions here
}
val result = function()
suspend 함수는 일반 메소드 사용이 블로킹되는 곳에서 일시 중지한다. 예를 들어 RateLimiter
가 속도 제한에 따라 호출을 잠시 지연시켜야 한다면, 건내받은 함수를 실행하기 전 호출을 잠시 중지한다.
넘겨진 suspend 함수의 코루틴 컨텍스트는 변경되지 않는다.
Usage - Flow
CircuitBreaker
, RateLimiter
, Retry
, TimeLimiter
를 위한 Flow<T>
전용 익스텐션을 몇 가지씩 정의해 놨다. 연산자 체이닝 순서는 중요한데, resilience 프리미티브가 평가되는 순서와 직접적인 관련이 있다. 다음 예제에서 flowOf(1).retry(...).timeLimiter(...)
를 살펴보면, 제공한 TimeLimiter 기간 내에 재시도를 모두 완료해야 한다.
val retry = Retry.ofDefaults()
val rateLimiter = RateLimiter.ofDefaults()
val timeLimiter = TimeLimiter.ofDefaults()
val circuitBreaker = CircuitBreaker.ofDefaults()
flowOf(1, 2, 3)
.retry(retry)
.rateLimiter(rateLimiter)
.timeLimiter(timeLimiter)
.circuitBreaker(circuitBreaker)
.collect { println(it) }
Bulkhead
Bulkhead
로 suspend 함수나 Flow를 데코레이트할 땐 maxWaitDuration
설정 값에 특히 주의해야 한다. maxWaitDuration
이 0이 아니면 최대 대기 시간에 도달하거나 권한을 획득할 때까지 호출을 블로킹하게 된다. 이때 블로킹은 디스패처 Dispatchers.IO
로만 제한된다. 이렇게하면 블로킹 API 사용으로 인해 발생하는 성능 이슈를 약간은 완화할 수 있긴 하지만, 최대 대기 시간이 0이 아닌 Bulkhead에는 이 익스텐션 함수를 권하지 않는다.
코루틴 스코프가 정상적으로든 비정상적으로든 취소되고 나면 획득한 권한을 해제한다. 그 후에는 성공이나 실패 이벤트를 기록하지 않는다.
스레드 풀 기반 bulkhead를 위한 익스텐션 함수는 제공하지 않는다.
CircuitBreaker
CircuitBreaker
를 사용해서 suspend 함수나 Flow를 데코레이트할 땐 다른 중단점(suspension point)이 생기지 않는다. 데코레이팅된 Flow의 경우, 서킷 브레이커가 OPEN
상태일 때 수집을 시도하면 CallNotPermittedException
이 발생한다.
코루틴 스코프가 정상적으로든 비정상적으로든 취소되고 나면 획득한 권한을 해제한다. 그 후에는 성공이나 실패 이벤트를 기록하지 않는다.
Rate Limiter
RateLimiter
로 데코레이팅된 suspend 함수는 속도 제한에 도달하면 데코레이팅된 함수를 실행하기 전에 delay()
를 사용해 잠시 중지한다.
RateLimiter로 데코레이팅된 Flow는 속도 제한에 도달하면 수집을 시도할 때 delay()
를 호출한다.
Retry
Retry
로 데코레이팅된 suspend 함수와 Flow는 재시도 사이 사이에 delay()
를 사용해 일시 중지한다.
Time Limiter
TimeLimiter
익스텐션 함수는 receiver의 설정에 있는 타임 아웃을 kotlinx-coroutines
의 withTimeout()
에 사용한다. 이게 의미하는 바는 특히 다음과 같다:
- 타임 아웃이 발생했을 땐, suspend가 아닌 일반 함수를 위한 메소드에서처럼
TimeoutException
이 발생하는 게 아니라TimeoutCancellationException
이 발생한다. - 타임 아웃이 발생하면 suspend가 아닌 일반 함수의 메소드에서처럼 스레드를 중단하는 대신에 코루틴이 취소된다.
- 건내준 블록은 타임 아웃이 발생하고 나서는 취소 가능한 suspend 함수 호출에서만 중지할 수 있다.
cancelRunningFuture
설정은 무시된다.cancelRunningFuture
가false
로 설정돼 있어도 타임 아웃이 발생하면 suspend 함수는 항상 취소된다.
TimeLimiter
로 데코레이트된 Flow는 수집을 시작하고 나면 설정한 제한 내에 전체 Flow를 컨슘하도록 만들 거다.
Next :Feign
feign 프레임워크에 서킷 브레이커, 속도 제한, 폴백을 적용할 수 있는 resilience4j-feign 모듈 소개
전체 목차는 여기에 있습니다.