Resilience4j中有一个特殊模块(Resilience4j -Retry),它是为Java8和函数式编程设计的容错库,它是具有最小依赖性的轻量级库(主要是vavr)
当你重试时,有很多例子:
- 用于远程系统调用的跨微服务通信,其中很可能还需要添加断路器逻辑
- 如果您有业务或功能逻辑需要获得一致的结束状态,并且很可能是异步流
好的,你需要做什么才能开始使用resileience4j重试:
如果你使用maven:
<dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-retry</artifactId> <version>0.13.2</version> </dependency> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-core</artifactId> <version>0.13.2</version> </dependency>
|
重试模块可以有以下功能:
- 同步重试和异步重试
- 关于异常或响应谓词的Rety,如果您想要重试特定的响应值而不仅仅是抛出异常,这可能很有用
- 重试配置的退避策略加上最大重试次数
- 忽略不重试的异常集
- 它支持checked(添加了异常处理)和未检查的函数执行(ex Function,Supplier,Callable,Runnable ..)
- 如果需要,它可以与spring集成。
如何配置异步重试,在Github上测试resilience4j重试的完整代码:
// Given the HelloWorldService returns Hello world given(helloWorldService.returnHelloWorld()) .willReturn(completedFuture("Hello world"));
final AsyncRetry retryContext = AsyncRetry.of("retryConfig", // we set the response type to String RetryConfig.<String>custom() // max retry attempts .maxAttempts(3) // what are the ignore exception to no retry on .ignoreExceptions(IllegalStateException.class) // what are the exceptions to try on .retryExceptions(TimeoutException.class) // retry if the response contains world .retryOnResult(s -> s.contains("world")) // retry backoff strategy, IntervalFunction has many built in interface functions you can check it out .intervalFunction(IntervalFunction.ofExponentialBackoff()) .build());
// Decorate the invocation of the HelloWorldService Supplier<CompletionStage<String>> supplier = AsyncRetry.decorateCompletionStage( retryContext, scheduler, () -> helloWorldService.returnHelloWorld());
// When String result = awaitResult(supplier); // Then the helloWorldService should be invoked 1 time BDDMockito.then(helloWorldService).should(Mockito.times(3)).returnHelloWorld(); Assertions.assertEquals(result, "Hello world");
|
对于同步调用,您有许多选项(Supplier , Callable , Function 。。)
// Given the HelloWorldService returns Hello world BDDMockito.given(helloWorldService.returnHelloWorld()).willReturn("Hello world"); // Create a Retry with default configuration final RetryConfig tryAgain = RetryConfig.<String>custom().retryOnResult(s -> s.contains("Hello world")) .maxAttempts(2).build(); Retry retry = Retry.of("id", tryAgain); // Decorate the invocation of the HelloWorldService Supplier<String> supplier = Retry.decorateSupplier(retry, helloWorldService::returnHelloWorld); // When String result = supplier.get(); // Then the helloWorldService should be invoked 1 time BDDMockito.then(helloWorldService).should(Mockito.times(2)).returnHelloWorld(); assertThat(result).isEqualTo("Hello world");
|