开始Resilience4j-retry 异常重试模块的学习

本文介绍了如何在Resilience4j中学习和使用Retry模块,包括创建RetryRegistry,配置重试策略,装饰函数式接口以及处理RegistryEvent。着重讲解了自定义配置和IntervalFunction的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重试

开始Resilience4j-retry模块的学习

创建 RetryRegistry

就像断路器模块一样,这么模块提供了在内存中的RetryRegistry,你可以使用这个管理(创建和检索)Retry实例。

RetryRegistry retryRegistry = RetryRegistry.ofDefaults();

创建和配置重试

你可以提供一个自定义的全局RetryConfig,为了创建一个自定义的全局RetryConfig,可以使用建造者模式对RetryConfig进行配置。

  • 最大的重试次数 。
  • 连续两次重试之间的时间间隔。
  • 自定义断言机制,评估一个响应是否可以触发重试机制。
  • 自定义断言机制,评估一个异常是否可以出发重试机制。
  • 定义一个异常的列表,这些异常能够触发重试机制。
  • 定义一个异常的列表,这些异常应该被忽略并且不会触发重试机制。
属性默认值描述
maxAttempts3最大重试次数
waitDuration500 [ms]两次重试之间的时间间隔
intervalFunctionnumOfAttempts -> waitDuration修改重试间隔的函数。默认情况下,等待时间保持不变。
retryOnResultPredicateresult -> false配置用于计算是否应重试的断言。如果要重试,断言必须返回true,否则返回false。
retryOnExceptionPredicatethrowable -> true配置一个断言,判断某个异常发生时,是否要进行重试。如果要重试,断言必须返回true,否则必须返回false。
retryExceptionsempty配置一个Throwable类型的列表,被记录为失败类型,需要进行重试,支持子类型。
ignoreExceptionsempty配置一个Throwable类型的列表,被记录为忽略类型,不会进行重试,支持子类型。
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);

装饰和执行函数式接口

正如你所想的一样,重试有所有高阶装饰函数,就像断路器一样。你可以使用Retry对Callable, Supplier, Runnable, Consumer, CheckedRunnable, CheckedSupplier, CheckedConsumer 或者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");

处理发出的RegistryEvent事件

你可以注册事件的处理者,并且在Retry创建、替换和删除时进行响应。

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

使用自定义的IntervalFunction

如果不想在重试之间使用固定的等待时间,可以配置IntervalFunction,该函数用于计算每次尝试的等待时间。Resilience4j提供了几种工厂方法来简化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();
Resilience4J 是一个轻量级的 Java 库,它专注于提供故障处理和恢复策略,包括对 Fallback 和 Retry 的支持。在 Spring Cloud 中,Fegin 是 Ribbon 的客户端模块,用于负载均衡和服务发现。 如果你想在 Resilience4J 中实现对 Fegin 接口的重试功能,首先需要做的是添加 Resilience4J 的依赖到你的项目中。然后,可以按照以下步骤操作: 1. **配置**: 创建一个 `RetryPolicy` 对象来定义重试策略,比如最大重试次数、延迟时间和错误过滤规则等。例如: ```java RetryPolicy retryPolicy = RetryPolicy.builder() .maxRetries(3) // 最大尝试次数 .delayFunction(RetryDelay.ofExponentialBackoff(Duration.ofMillis(100), Duration.ofMillis(500))) // 每次失败后的延迟增长 .build(); ``` 2. **装饰器模式**: 使用 `RetryableHttpResponseClient` 或者 `@Retryable` 注解将 Fegin 的 Client 装饰起来,应用你刚刚创建的重试策略: ```java @Retryable(retryPolicy = retryPolicy) public HttpClient getHttpClient() { return Fegin.create(HttpClients.custom().build()); } ``` 或者如果你使用的是 Functional API: ```java Optional<HttpClient> client = CircuitBreakerircuitbreaker.decorate( () -> Fegin.create(HttpClients.custom().build()), retryPolicy ); ``` 3. **调用服务**: 现在你可以像平常那样调用 `HttpClient`,Resilience4J 会在后台自动处理重试逻辑,如果请求失败并且满足重试条件,它会自动重试直到达到最大次数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值