Spring Retry 的使用和原理

本文详细介绍了Spring Retry的使用,包括如何引入、启用重试(@EnableRetry)和注解@Retryable的配置。讲解了重试策略如SimpleRetryPolicy、AlwaysRetryPolicy等,退避策略如FixedBackOffPolicy、ExponentialBackOffPolicy,并提到了@Recover的恢复处理。同时探讨了@SpringBootApplication背后的@EnableRetry如何开启AOP并注册切入点和增强。
摘要由CSDN通过智能技术生成

Spring Retry提供了自动重新调用失败的操作的功能。这在错误可能是暂时性的(例如瞬时网络故障)的情况下很有用。Spring Retry提供对流程和基于策略的行为的声明式控制,易于扩展和自定义。接下来,本文将带大家了解 Spring Retry 的使用方法和部分源码解析

引入spring-retry 相关包

使用spring-retry ,我们只需引入spring-retry 和 aop 的包即可,以 maven 为例:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.1.5.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
</dependency>

使用 spring-retry

@EnableRetry

​ 首先我们需要使用@EnableRetry 注解启用Retry,注册 Retryable 的切点和拦截方法

@Retryable

​ 在我们想要重试的方法上增加@Retryable 注解

@Service
@EnableRetry
public class SpringRetryTest {
   

  @Retryable
  public void test() {
   
      System.out.println("test");
      throw new RuntimeException();
  }
}

这样我们就可以实现一个简单的重试功能了,是不是非常的方便!当然 Spring Retry 支持很多复杂功能的实现,接下来我们就来看一下他的强大功能吧!

@Retryable 参数
  • interceptor

    自定义重试拦截器bean名称,用于可重试方法。与其他属性互斥。

    //新增自定义拦截器
    @Component
    public class RetryTestInterceptor implements MethodInterceptor {
         
    
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
         
          	//实现具体的拦截策略
            System.out.println("retry test interceptor");
            return invocation.proceed();
        }
    }
    //参数为自定义拦截器的 bean 名称
    @Retryable(interceptor = "retryTestInterceptor")
    
    
  • value

  • include

    value 与 include 含义相同,表示可重试的异常类型。默认为空,如果同时exclude 也为空则会重试所有异常。但在使用时需要注意

        @Retryable(value = {
         RuntimeException.class})
    
  • exclude

    不可重试的异常类型。默认为空(如果include也为为空,将重试所有异常)。如果include为空但exclude 不为空,则重试非 exclude 中的异常

        @Retryable(exclude = {
         RuntimeException.class})
    
  • label

    统计报告的唯一标签。如果未提供,则调用者可以选择忽略它或提供默认值。

  • stateful

    标记为表示重试是有状态的,默认为 false,在 interceptor 参数中有提到,参数不同使用的拦截器不同,后面我们会讲到不同拦截的作用

  • maxAttempts

    最大重试次数,默认是 3

  • maxAttemptsExpression

    最大尝试次数的表达式,表达式一旦设置了值,则会覆盖 maxAttempts 的值

    //执行 testBean 的 attempts() 方法,获取重试次数    
    @Retryable(maxAttemptsExpression = "#{@testBean.attempts()}")
    
  • backoff

    用于重试退避策略,比如每隔2s 重试一次,每次重试间隔时间等等,详见@Backoff注解

    //第一次延迟 1s 重试,第二次延迟 2s,第三次延迟 4s,...    
    @Retryable(backoff = @Backoff(delay = 1000L, multiplier = 2))
    
  • exceptionExpression

    异常处理表达式,ExpressionRetryPolicy中使用,执行完父类的 canRetry 之后,需要校验 exceptionExpression 的值,为 true 则可以重试

    //执行 testBean 的 shouldRetry() 方法,如果为 true,则允许重试  
    @Retryable(exceptionExpression = "#{@testBean.shouldRetry()}")
    
  • listeners

    重试监听器的 bean 名称。

重试策略

Spring Retry 提供了多种重试策略,比如

  • SimpleRetryPolicy

    默认重试策略,简单的重试策略,它对一组命名的异常*(和子类)重试固定次数。尝试次数包括初始尝试

  • AlwaysRetryPolicy

    始终允许重试策略,

  • MaxAttemptsRetryPolicy

    简单重试策略,仅通过重试次数判断是否能够重试。不建议直接使用它。

  • TimeoutRetryPolicy

    超时重试策略,仅在尚未超时的情况下允许重试。

  • NeverRetryPolicy

    允许第一次尝试,但不允许重试。

还有很多重试策略就不一一介绍了,大家可以自行了解,当然我们也可以通过实现 RetryPolicy 自定义重试策略。

退避策略

退避策略就是我们上面提到的 @Backoff 注解实现的功能,那么我们首先看一下@Backoff 的参数

@Backoff 参数

  • value

    默认为 1000, 与 delay 作用相同,表示延迟的毫秒数。当 delay 非 0 时,此参数忽略。

  • delay

    默认为 0。在指数情况下用作初始值,在统一情况下用作*的最小值。当此元素的值为0时,将采用元素value的值,否则将采用此元素的值,并且将忽略value。

  • maxDelay

    默认为 0。重试之间的最大等待时间(以毫秒为单位)。如果小于delay,那么将应用默认值为30000L

  • multipler

    默认为 0。如果为正,则用作乘法器以生成下一个退避延迟。返回一个乘法器,用于计算下一个退避延迟

  • delayExpression

    评估标准退避期的表达式。在指数情况下用作初始值*,在均匀情况下用作最小值。覆盖 delay。

  • maxDelayExpression

    该表达式计算重试之间的最大等待时间(以毫秒为单位)。 如果小于 delay,那么将应用30000L 为默认值。覆盖 maxDelay。

  • multiplierExpression

    评估为用作乘数的值,以生成退避的下一个延迟。覆盖multiplier。 返回一个乘数表达式,用于计算下一个退避延迟

  • random

    默认为 false,在指数情况下 multiplier> 0 将此值设置为 true 可以使后退延迟随机化,从而使最大延迟乘以前一延迟,并且两个值之间的分布是均匀的。

@Backoff 的参数会影响我们使用哪种退避策略

  • FixedBackOffPolicy

    默认退避策略,每 1 秒重试 1 次

  • ExponentialBackOffPolicy

    指数退避策略&

  • 10
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值