使用resilience4j-retry实现函数式重试

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");

原文 

https://www.jdon.com/50942

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 使用resilience4j-retry实现函数式重试

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址