在调用第三方接口或者使用mq时,会出现网络抖动,连接超时等网络异常,所以需要重试。为了使处理更加健壮并且不太容易出现故障,后续的尝试操作,有时候会帮助失败的操作最后执行成功。例如,由于网络故障或数据库更新中的DeadLockLoserException导致Web服务或RMI服务的远程调用可能会在短暂等待后自行解决。 为了自动执行这些操作的重试,Spring Batch具有RetryOperations策略。不过该重试功能从Spring Batch 2.2.0版本中独立出来,变成了Spring Retry模块。

快速集成的代码样例:

@Configuration
@EnableRetry
public class Application {@Beanpublic Service service() {return new Service();}}@Service
class Service {@Retryable(RemoteAccessException.class)public service() {// ... do something}
}

引入依赖

    <dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId></dependency>

需要引入Spring-retry和aspectjweaver的依赖。

入口类


@SpringBootApplication
@EnableRetry
public class SpringbootRetryApplication {public static void main(String[] args) {SpringApplication.run(SpringbootRetryApplication.class, args);}
}

入口类上开启retry的拦截,使用@EnableRetry注解。

Service

@Service
public class PayService {private Logger logger = LoggerFactory.getLogger(getClass());private final int totalNum = 100000;@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5))public int minGoodsnum(int num) throws Exception {logger.info("减库存开始" + LocalTime.now());try {int i = 1 / 0;} catch (Exception e) {logger.error("illegal");}if (num <= 0) {throw new IllegalArgumentException("数量不对");}logger.info("减库存执行结束" + LocalTime.now());return totalNum - num;}
}

@Retryable注解

被注解的方法发生异常时会重试

  • value:指定发生的异常进行重试
  • include:和value一样,默认空,当exclude也为空时,所有异常都重试
  • exclude:指定异常不重试,默认空,当include也为空时,所有异常都重试
  • maxAttemps:重试次数,默认3
  • backoff:重试补偿机制,默认没有

@Backoff注解

  • delay:指定延迟后重试
  • multiplier:指定延迟的倍数,比如delay=5000l,multiplier=2时,第一次重试为5秒后,第二次为10秒,第三次为20秒

@Recover

当重试到达指定次数时,被注解的方法将被回调,可以在该方法中进行日志处理。需要注意的是发生的异常和入参类型一致时才会回调。

测试类

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRetryApplicationTests {@Autowiredprivate PayService payService;@Testpublic void payTest() throws Exception {int store = payService.minGoodsnum(-1);System.out.println("库存为:" + store);}}

运行的控制台结果如下:

可以看到,三次之后抛出了IllegalArgumentException异常。

当重试耗尽时,RetryOperations可以将控制传递给另一个回调,即RecoveryCallback。Spring-Retry还提供了@Recover注解,用于@Retryable重试失败后处理方法,此方法里的异常一定要是@Retryable方法里抛出的异常,否则不会调用这个方法。

@Recover
public int recover(Exception e) {logger.warn("减库存失败!!!" + LocalTime.now());return totalNum;
}

在Service中,加上如上的方法之后,进行测试。

可以看到当三次重试执行完之后,会调用Recovery方法,也不会再次抛出异常。

说明:

1、使用了@Retryable的方法不能在本类被调用,不然重试机制不会生效。也就是要标记为@Service,然后在其它类使用@Autowired注入或者@Bean去实例才能生效。

2、要触发@Recover方法,那么在@Retryable方法上不能有返回值,只能是void才能生效。

3、使用了@Retryable的方法里面不能使用try...catch包裹,要在发放上抛出异常,不然不会触发。

4、在重试期间这个方法是同步的,如果使用类似Spring Cloud这种框架的熔断机制时,可以结合重试机制来重试后返回结果。

5、Spring Retry不只能注入方式去实现,还可以通过API的方式实现,类似熔断处理的机制就基于API方式实现会比较宽松。

总结

本文主要讲了在Spring Boot项目中的Spring-Retry简单应用,主要是基于注解配置一些重试的策略,使用比较简单。主要的适用场景为在调用第三方接口或者使用mq时。由于会出现网络抖动,连接超时等网络异常,这时就需要重试。

本文的代码: https://github.com/keets2012/Spring-Cloud_Samples/tree/master/springboot-retry

参考:

https://www.cnblogs.com/EasonJim/p/7684649.html

https://www.jianshu.com/p/cc7abf831900

Spring异常重试框架Spring Retry相关推荐

  1. java retry_Spring异常重试框架Spring Retry详解

    Spring Retry支持集成到Spring或者Spring Boot项目中,而它支持AOP的切面注入写法,所以在引入时必须引入aspectjweaver.jar包. 快速集成的代码样例: @Con ...

  2. Spring异常重试机制 - Spring Retry

    目录 一 . 引入依赖 二 . 在启用类或业务类上添加@EnableRetry注解启用重试机制(在启用类上添加全局有效 , 在业务类上添加仅当前有效) 三 . 使用@Retryable实现重试 四 . ...

  3. 重试框架Spring retry实践

    spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断.对于重试是有场景限制的,不是什么场景都适合重试,比如参数校验不合法.写操作等(要考虑写是否幂等)都不适合 ...

  4. 芋道 Spring Boot 安全框架 Spring Security 入门

    本文在提供完整代码示例,可见 GitHub - YunaiV/SpringBoot-Labs: 一个涵盖六个专栏:Spring Boot 2.X.Spring Cloud.Spring Cloud A ...

  5. Spring Boot中使用Spring-Retry重试框架

    文章目录 Spring Boot中使用Spring-Retry重试框架 Maven依赖 注解使用 开启Retry功能 注解`@Retryable` 注解`@Recover` 注解`@CircuitBr ...

  6. 【Spring教程】框架体系介绍

    文章目录 一.简介 二.模块 1.核心容器(Core Container) 2.应用上下文(Context) 3.Spring的AOP模块 4.JDBC抽象和DAO模块 5.对象/关系映射集成模块 6 ...

  7. Spring源码之Spring的大体框架

    Spring源码(一)----了解Spring的大体框架 Spring的源码数量特别多,在我下载了Spring FrameWork源码后,发现有些无从学起,那么就一步一步来,先不管其他,先了解一下Sp ...

  8. java retry_Spring重试支持Spring Retry的方法

    本文介绍了Spring重试支持Spring Retry的方法,分享给大家,具体如下: 第一步.引入maven依赖 org.springframework.boot spring-boot-starte ...

  9. 具有中央异常处理和VO验证的Spring Data JPA –框架

    1.简介 一段时间以来,Spring框架已成为事实上的标准,可以创建任何基于REST API的应用程序. Spring提供了各种现成的组件,以避免编写重复而繁琐的样板代码. 另外,关于Spring的美 ...

最新文章

  1. storm源码之storm代码结构【译】
  2. 记录,再次运行vue项目报错POST http://127.0.0.1:8888/api/private/v1/login/login
  3. 搜索插入位置—leetcode35
  4. js 如何获取class的元素 以及创建方法getElementsByClassName
  5. table tr th td
  6. 三、Linux 开机、重启和用户登录注销
  7. 菜鸟学习C++练笔之整理搜狗2008版语料库--获取分类语料库
  8. leetcode48:矩阵旋转
  9. 整人vbs格式小代码
  10. px和毫米的换算_px与厘米换算(px怎么转换为cm)
  11. 日历控件My97DatePicker使用--onchange不生效
  12. ​依图上市,AI 四小龙走向「三岔路口」
  13. MySQL从删库到跑路(3):神奇的select
  14. 深度学习分析--TextCNN算法原理及分类实现
  15. 计算机语言有许多种其中与硬件直接相关的是,【单选题】计算机语言有许多种,其中与硬件直接相关的是 A. 机器语言 B. 网络语言 C. 高级语言 D. 自然语言...
  16. 关于JS获取clientWidth大小一直为0的问题
  17. Swift 基础 枚举详解(代码)
  18. 创业明星|她曾是中国互联网界最年轻的首席运营官:不靠美貌一样征服
  19. 使用webpack脚手架创建一个vue项目
  20. 从大数据量分库分表 MySQL 合并迁移数据到 TiDB

热门文章

  1. ASP.NET 前端Ajax获取数据并刷新
  2. 域组策略--+域控中组策略基本设置
  3. Asp.net2.0里访问Web.config的Section的示例
  4. c# char unsigned_C 中 char、signed char 和 unsigned char 的区别
  5. c语言下列循环的循环次数,在C语言中,若i=3,则语句 while (i) { i--; break;}的循环次数为 答案:1...
  6. C语言指针作为参数的传递问题
  7. linux中物理cpu、逻辑cpu以及core、vcore
  8. python把文件读成字节流_Python中struct模块对字节流/二进制流的操作教程
  9. 2020年5月数据库流行度排行:疫情下开源数据库逆势增长,新基建下国产数据库迎机遇...
  10. MySQL访问行更新慢、用户线程大量堆积竟是因为它