resilience4j 공식 레퍼런스를 한글로 번역한 문서입니다.
전체 목차는 여기에 있습니다.
목차
- Introduction
- Create a BulkheadRegistry
- Create and configure a Bulkhead
- Create and configure a ThreadPoolBulkhead
- Decorate and execute a functional interface
- Consume emitted RegistryEvents
- Consume emitted BulkheadEvents
Introduction
Resilience4j는 동시 실행 횟수를 제한하는 데 활용할 수 있는 bulkhead 패턴을 두 가지 구현체로 제공한다.
- 세마포어를 사용하는
SemaphoreBulkhead
. - 유한 큐와 고정 스레드 풀을 사용하는
FixedThreadPoolBulkhead
.
SemaphoreBulkhead
는 다양한 스레딩 모델과 I/O 모델에서 잘 작동할 거다. 이 구현체는 세마포어 기반으로, 히스트릭스와는 달리 “이름 뿐인” 스레드 풀 옵션을 제공하지 않는다. bulkhead 설정에 맞는 적당한 스레드 풀 사이즈를 선택하는 건 클라이언트 몫이다.
Create a BulkheadRegistry
이 모듈은 CircuitBreaker 모듈과 동일하게 Bulkhead 인스턴스들을 관리(생성/조회)할 수 있는 인 메모리 BulkheadRegistry
와 ThreadPoolBulkheadRegistry
를 제공한다.
BulkheadRegistry bulkheadRegistry = BulkheadRegistry.ofDefaults();
ThreadPoolBulkheadRegistry threadPoolBulkheadRegistry =
ThreadPoolBulkheadRegistry.ofDefaults();
Create and configure a Bulkhead
커스텀 글로벌 BulkheadConfig
를 제공하는 것도 가능하다. 커스텀 글로벌 BulkheadConfig
를 생성할 땐 BulkheadConfig 빌더를 사용하면 된다. 이 빌더를 통해 다음과 같은 프로퍼티를 설정할 수 있다.
Config property | Default value | Description |
---|---|---|
maxConcurrentCalls | 25 | bulkhead에서 최대로 허용할 병렬 실행 수 |
maxWaitDuration | 0 | bulkhead가 포화 상태일 때 진입하려는 스레드를 블로킹할 최대 시간. |
// Create a custom configuration for a Bulkhead
BulkheadConfig config = BulkheadConfig.custom()
.maxConcurrentCalls(150)
.maxWaitDuration(Duration.ofMillis(500))
.build();
// Create a BulkheadRegistry with a custom global configuration
BulkheadRegistry registry = BulkheadRegistry.of(config);
// Get or create a Bulkhead from the registry -
// bulkhead will be backed by the default config
Bulkhead bulkheadWithDefaultConfig = registry.bulkhead("name1");
// Get or create a Bulkhead from the registry,
// use a custom configuration when creating the bulkhead
Bulkhead bulkheadWithCustomConfig = registry.bulkhead("name2", custom);
Create and configure a ThreadPoolBulkhead
커스텀 글로벌 ThreadPoolBulkheadConfig
를 제공하는 것도 가능하다. 커스텀 글로벌 ThreadPoolBulkheadConfig
를 생성할 땐 ThreadPoolBulkheadConfig
빌더를 사용하면 된다. 이 빌더를 통해 다음과 같은 프로퍼티를 설정할 수 있다.
Config property | Default value | Description |
---|---|---|
maxThreadPoolSize | Runtime.getRuntime() .availableProcessors() | 스레드 풀의 최대 사이즈를 설정한다. |
coreThreadPoolSize | Runtime.getRuntime() .availableProcessors() - 1 | 스레드 풀의 코어 사이즈를 설정한다. |
queueCapacity | 100 | 큐 용량을 설정한다. |
keepAliveDuration | 20 [ms] | 스레드 수가 코어보다 많을 때 초과분 만큼의 스레드가 유휴 상태로 새 태스크를 기다리는 최대 시간으로, 이 시간이 지나면 유휴 스레드는 종료된다. |
ThreadPoolBulkheadConfig config = ThreadPoolBulkheadConfig.custom()
.maxThreadPoolSize(10)
.coreThreadPoolSize(2)
.queueCapacity(20)
.build();
// Create a BulkheadRegistry with a custom global configuration
ThreadPoolBulkheadRegistry registry = ThreadPoolBulkheadRegistry.of(config);
// Get or create a ThreadPoolBulkhead from the registry -
// bulkhead will be backed by the default config
ThreadPoolBulkhead bulkheadWithDefaultConfig = registry.bulkhead("name1");
// Get or create a Bulkhead from the registry,
// use a custom configuration when creating the bulkhead
ThreadPoolBulkheadConfig custom = BulkheadConfig.custom()
.maxThreadPoolSize(5)
.build();
ThreadPoolBulkhead bulkheadWithCustomConfig = registry.bulkhead("name2", custom);
Decorate and execute a functional interface
짐작했겠지만, Bulkhead도 CircuitBreaker에 있던 고차원 데코레이터 함수를 모두 가지고 있다. Callable
, Supplier
, Runnable
, Consumer
, CheckedRunnable
, CheckedSupplier
, CheckedConsumer
, CompletionStage
라면 모두 Bulkhead로 데코레이트할 수 있다.
// Given
Bulkhead bulkhead = Bulkhead.of("name", config);
// When I decorate my function
CheckedFunction0<String> decoratedSupplier = Bulkhead
.decorateCheckedSupplier(bulkhead, () -> "This can be any method which returns: 'Hello");
// and chain an other function with map
Try<String> result = Try.of(decoratedSupplier)
.map(value -> value + " world'");
// Then the Try Monad returns a Success<String>, if all functions ran successfully.
assertThat(result.isSuccess()).isTrue();
assertThat(result.get()).isEqualTo("This can be any method which returns: 'Hello world'");
assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1);
ThreadPoolBulkheadConfig config = ThreadPoolBulkheadConfig.custom()
.maxThreadPoolSize(10)
.coreThreadPoolSize(2)
.queueCapacity(20)
.build();
ThreadPoolBulkhead bulkhead = ThreadPoolBulkhead.of("name", config);
CompletionStage<String> supplier = ThreadPoolBulkhead
.executeSupplier(bulkhead, backendService::doSomething);
Consume emitted RegistryEvents
BulkheadRegistry에 이벤트 컨슈머를 등록해서 Bulkhead가 생성, 교체, 삭제될 때마다 필요한 로직을 실행할 수 있다.
BulkheadRegistry registry = BulkheadRegistry.ofDefaults();
registry.getEventPublisher()
.onEntryAdded(entryAddedEvent -> {
Bulkhead addedBulkhead = entryAddedEvent.getAddedEntry();
LOG.info("Bulkhead {} added", addedBulkhead.getName());
})
.onEntryRemoved(entryRemovedEvent -> {
Bulkhead removedBulkhead = entryRemovedEvent.getRemovedEntry();
LOG.info("Bulkhead {} removed", removedBulkhead.getName());
});
Consume emitted BulkheadEvents
BulkHead는 BulkHeadEvent 스트림을 방출한다. 방출하는 이벤트는 실행 허용, 실행 거절 & 실행 완료, 이렇게 두 가지 타입이 있다. 이 이벤트를 컨슘하려면 이벤트 컨슈머를 등록해야 한다.
bulkhead.getEventPublisher()
.onCallPermitted(event -> logger.info(...))
.onCallRejected(event -> logger.info(...))
.onCallFinished(event -> logger.info(...));
Next :Bulkhead Examples
벌크 헤드 사용 예시 한글 번역
전체 목차는 여기에 있습니다.