Start learning the Resilience4j-retry exception retry module

Retry

Start learning the Resilience4j-retry module

CreateRetryRegistry

Just like the circuit breaker module, this module provides in-memory RetryRegistryRetry instances that you can use to manage (create and retrieve).

RetryRegistry retryRegistry = RetryRegistry.ofDefaults();

Create and configure retry

You can provide a custom global RetryConfig. In order to create a custom global RetryConfig, you can configure the RetryConfig using the builder pattern.

  • The maximum number of retries.
  • The time interval between two consecutive retries.
  • Customize the assertion mechanism to evaluate whether a response can trigger the retry mechanism.
  • Customize the assertion mechanism to evaluate whether an exception can trigger the retry mechanism.
  • Define a list of exceptions that can trigger the retry mechanism.
  • Define a list of exceptions that should be ignored and not trigger a retry mechanism.
Attributes Defaults describe
maxAttempts 3 Maximum number of retries
waitDuration 500 [ms] The time between retries
intervalFunction numOfAttempts -> waitDuration Function to modify the retry interval. By default, the wait time remains unchanged.
retryOnResultPredicate result -> false Configure the assertion used to calculate whether it should be retried. The assertion must return true if it is to be retried, false otherwise.
retryOnExceptionPredicate throwable -> true Configure an assertion to determine whether to retry when an exception occurs. The assertion must return true if it is to be retried, and false otherwise.
retryExceptions empty Configure a list of Throwable types, which are recorded as failure types, need to be retried, and support subtypes.
ignoreExceptions empty Configure a list of Throwable types, which are recorded as ignored types, will not be retried, and support subtypes.
RetryConfig config = RetryConfig.custom()
  .maxAttempts(2)
  .waitDuration(Duration.ofMillis(1000))
  .retryOnResult(response -> response.getStatus() == 500)
  .retryOnException(e -> e instanceof WebServiceException)
  .retryExceptions(IOException.class, TimeoutException.class)
  .ignoreExceptions(BusinessException.class, OtherBusinessException.class)
  .build();

// 使用自定义的配置创建RetryRegistry
RetryRegistry registry = RetryRegistry.of(config);

// 使用默认的配置从Registry中获取和创建一个Retry
Retry retryWithDefaultConfig = registry.retry("name1");

// 使用自定义的配置从Registry中获取和创建一个Retry
RetryConfig custom = RetryConfig.custom()
    .waitDuration(Duration.ofMillis(100))
    .build();

Retry retryWithCustomConfig = registry.retry("name2", custom);

Decorate and implement functional interfaces

As you might imagine, retries have all the higher-order decorating functions, just like circuit breakers. You can use Retry to decorate Callable, Supplier, Runnable, Consumer, CheckedRunnable, CheckedSupplier, CheckedConsumeror .CompletionStage

// 假设有一个HellowWorldService并抛出异常
HelloWorldService  helloWorldService = mock(HelloWorldService.class);
given(helloWorldService.sayHelloWorld())
  .willThrow(new WebServiceException("BAM!"));

// 使用默认的配置创建重试
Retry retry = Retry.ofDefaults("id");
// 使用Retry对HelloWorldService进行装饰
CheckedFunction0<String> retryableSupplier = Retry
  .decorateCheckedSupplier(retry, helloWorldService::sayHelloWorld);

// 进行方法调用
Try<String> result = Try.of(retryableSupplier)
  .recover((throwable) -> "Hello world from recovery function");

// helloWorldService的sayHelloWorld()方法将被调用3次
BDDMockito.then(helloWorldService).should(times(3)).sayHelloWorld();
// 异常应该被recovery方法处理
assertThat(result.get()).isEqualTo("Hello world from recovery function");

Handle the emitted RegistryEvent event

You can register event handlers and respond when Retry is created, replaced, and deleted.

RetryRegistry registry = RetryRegistry.ofDefaults();
registry.getEventPublisher()
  .onEntryAdded(entryAddedEvent -> {
    
    
    Retry addedRetry = entryAddedEvent.getAddedEntry();
    LOG.info("Retry {} added", addedRetry.getName());
  })
  .onEntryRemoved(entryRemovedEvent -> {
    
    
    Retry removedRetry = entryRemovedEvent.getRemovedEntry();
    LOG.info("Retry {} removed", removedRetry.getName());
  })

Use custom IntervalFunction

If you don't want to use a fixed wait time between retries, you can configure an IntervalFunction, which is used to calculate the wait time for each attempt. Resilience4j provides several factory methods to simplify the creation of IntervalFunction.

IntervalFunction defaultWaitInterval = IntervalFunction
  .ofDefaults();

// 当您只配置waitDuration时,此间隔函数在内部使用。
IntervalFunction fixedWaitInterval = IntervalFunction
  .of(Duration.ofSeconds(5));

IntervalFunction intervalWithExponentialBackoff = IntervalFunction
  .ofExponentialBackoff();

IntervalFunction intervalWithCustomExponentialBackoff = IntervalFunction
  .ofExponentialBackoff(IntervalFunction.DEFAULT_INITIAL_INTERVAL, 2d);

IntervalFunction randomWaitInterval = IntervalFunction
  .ofRandomized();

// 用自定义的intervalFunction覆盖默认的intervalFunction
RetryConfig retryConfig = RetryConfig.custom()
  .intervalFunction(intervalWithExponentialBackoff)
  .build();

おすすめ

転載: blog.csdn.net/ywtech/article/details/132662161