토리맘의 한글라이즈 프로젝트 logo 토리맘의 한글라이즈 프로젝트

resilience4j 공식 레퍼런스를 한글로 번역한 문서입니다.

전체 목차는 여기에 있습니다.

목차


Introduction

Resilience4j는 동시 실행 횟수를 제한하는 데 활용할 수 있는 bulkhead 패턴을 두 가지 구현체로 제공한다.

SemaphoreBulkhead는 다양한 스레딩 모델과 I/O 모델에서 잘 작동할 거다. 이 구현체는 세마포어 기반으로, 히스트릭스와는 달리 “이름 뿐인” 스레드 풀 옵션을 제공하지 않는다. bulkhead 설정에 맞는 적당한 스레드 풀 사이즈를 선택하는 건 클라이언트 몫이다.


Create a BulkheadRegistry

이 모듈은 CircuitBreaker 모듈과 동일하게 Bulkhead 인스턴스들을 관리(생성/조회)할 수 있는 인 메모리 BulkheadRegistryThreadPoolBulkheadRegistry를 제공한다.

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(...));

전체 목차는 여기에 있습니다.

<< >>

TOP