Spring-retry详解

什么是重试重试是指 , 当在一个程序运行过程中 , 突然遇到了例如网络延迟 , 中断等情况时 , 为了保证程序容错性 , 可用性 , 一致性等的一个措施 , 目前主流的框架大多都有一套自己的重试机制 , 例如 dubbo , mq , Spring 等
概要Spring 也自己实现了一套重试机制 , Spring Retry 是从 Spring batch 中独立出来的一个功能 , 主要功能点在于重试和熔断 , 目前已经广泛应用于 Spring Batch,Spring Integration, Spring for Apache Hadoop 等 Spring 项目 。spring retry 提供了注解和编程 两种支持 , 提供了 RetryTemplate 支持 , 类似 RestTemplate 。整个流程如下:

Spring-retry详解

文章插图
 
使用介绍Maven 依赖<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId></dependency><!-- also need to add Spring AOP into our project--><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId></dependency>注解使用开启 Retry 功能 , 需在启动类中使用 @EnableRetry 注解
@SpringBootApplication@EnableRetry@EnableSchedulingpublic class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}注解 @Retryable需要在重试的代码中加入重试注解 @Retryable
@Retryable(value = https://www.isolves.com/it/cxkf/kj/2023-05-18/RuntimeException.class)public void testRetry01() throws MyException {System.out.println("测试-value属性");throw new RuntimeException("出现了异常");}默认情况下 , 会重试 3 次 , 间隔 1 秒
重试配置通过 @Retryable 注解的属性 可以实现重试配置
  • Value()
  • includevalue 与 include 含义相同 , 表示可重试的异常类型 。默认为空 , 如果同时 exclude 也为空则会重试所有异常 。但在使用时需要注意
@Retryable(value = https://www.isolves.com/it/cxkf/kj/2023-05-18/RuntimeException.class)public void testRetry01() throws MyException {System.out.println("测试-value属性");throw new RuntimeException("出现了异常");}例:testRetry01 只会在程序抛出 RuntimeException 时 , 开启重试
  • exclude不可重试的异常类型 。默认为空(如果 include 也为为空 , 将重试所有异常) 。如果 include 为空但 exclude 不为空 , 则重试非 exclude 中的异常 @Retryable(exclude = RuntimeException.class)
    public void testRetry02() throws MyException {
    System.out.println("测试-value属性");
    throw new MyException("出现了异常");
    }例:testRetry02 在程序抛出 MyException 时 , 不会开启重试
  • maxAttempts
最大重试次数 , 默认为 3
  • maxAttemptsExpression
最大尝试次数的表达式 , 表达式一旦设置了值 , 则会覆盖 maxAttempts 的值 , maxAttemptsExpression 可以读取 application.yml 配置文件里的数据 , 也可以通过 SpEL 表达式计算对应的值
@Retryable(value = https://www.isolves.com/it/cxkf/kj/2023-05-18/MyException.class, maxAttemptsExpression = "${maxAttempts}")public void testRetry03() throws MyException {System.out.println("测试-maxAttemptsExpression属性");throw new MyException("出现了异常");}
Spring-retry详解

文章插图
 
例:testRetry03 会去读 properties 配置文件获取属性名为 maxAttempts 的值
@Retryable(value = https://www.isolves.com/it/cxkf/kj/2023-05-18/MyException.class,maxAttemptsExpression = "#{2+3}")public void testRetry04() throws MyException {System.out.println("测试-maxAttemptsExpression属性");throw new MyException("出现了异常");}例:testRetry04 会去通过 SqlEL 计算出对应的重试值
  • exceptionExpression
异常处理表达式 , ExpressionRetryPolicy 中使用 , 执行完父类的 canRetry 之后 , 需要校验 exceptionExpression 的值 , 为 true 则可以重试
@Retryable(value = https://www.isolves.com/it/cxkf/kj/2023-05-18/MyException.class, exceptionExpression = "#{@retryService.isRetry()}")public void testRetry05() throws MyException {System.out.println("测试-exceptionExpression");throw new MyException("出现了异常");}


推荐阅读