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

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

重试

开始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-Spring-Boot2 的功能与作用 `resilience4j-spring-boot2` 是 Resilience4j 提供的一个专门针对 Spring Boot 2 的集成模块,旨在简化开发者在微服务架构中实现容错机制的过程。以下是该包的主要功能、作用以及适用场景: #### 主要功能 1. **自动配置支持** `resilience4j-spring-boot2` 提供了基于 Spring Boot 自动化配置的能力,使得开发者可以通过简单的属性设置完成复杂的容错逻辑配置[^4]。 2. **注解驱动的编程模型** 开发者可以使用 Resilience4j 提供的一系列注解(如 `@CircuitBreaker`, `@Retry`, `@RateLimiter`, 和 `@Bulkhead`)轻松地将这些特性应用到方法级别,而无需手动管理装饰器链[^2]。 3. **监控指标集成** 支持通过 Micrometer 或 Actuator 集成,提供实时的健康状态和性能数据监控,便于运维人员及时发现潜在问题并采取措施[^4]。 4. **多种容错模式的支持** 包括但不限于断路器模式 (Circuit Breaker)、重试机制 (Retry)、限流策略 (Rate Limiter),以及资源隔离方案 (Bulkhead)[^2]。 #### 作用 - **提升系统的稳定性** 在分布式环境中,网络延迟或下游服务不可用等问题不可避免。借助于 `resilience4j-spring-boot2` 中内置的各种保护机制,应用程序可以在面对这些问题时表现出更强健的行为[^3]。 - **降低复杂度** 将原本可能非常繁琐的手动编码工作量减少至最小程度,仅需定义少量 YAML 属性或者添加几个 Java 注解即可启用强大功能。 - **增强用户体验** 当某些操作失败时,合理运用 Retries 可以提高成功率;当请求流量过大时,则可通过 Rate Limiters 来平滑负载压力,从而改善最终用户的交互体验[^2]。 #### 使用场景 1. **处理外部依赖不稳定的情况** 如果您的系统调用了第三方 API 并担心其偶尔会出现超时或其他错误响应,那么 Circuit Breaker 加上 Retry 组合将是理想的选择[^1]。 2. **控制并发访问数量** 对于那些共享有限硬件资源的操作来说,比如数据库连接池大小固定不变的情况下,采用 Bulkheads 能够有效防止因过度占用而导致整体崩溃的风险。 3. **预防突发流量冲击** 借助 RateLimiters 设置合理的速率上限值,即使遇到短时间内的大量涌入请求也能保持正常运转而不至于被压垮。 ```yaml # 示例:application.yml 配置片段展示如何开启特定功能 resilience4j.circuitbreaker: instances: backendA: registerHealthIndicator: true failureRateThreshold: 50 waitDurationInOpenState: 10s permittedNumberOfCallsInHalfOpenState: 3 slidingWindowSize: 10 minimumNumberOfCalls: 5 resilience4j.retry: instances: default: maxAttempts: 3 waitDuration: 100ms ``` ```java // 示例:Java 方法级注解方式演示实际应用场景下的代码写法 @Service public class ExampleService { @CircuitBreaker(name = "backendA", fallbackMethod = "fallback") public String doSomething() { // 实际业务逻辑... return "Success"; } private String fallback(Throwable throwable) { return "Fallback response due to error."; } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值