环境:SpringBoot3.2.5
1. 简介
业务功能重试机制通常在项目中是非常有必要的,特别是在处理外部系统调用(如HTTP请求、数据库操作、消息队列等)时。这些操作可能因网络波动、服务暂时不可用等原因而失败。重试机制可以提高系统的健壮性和用户体验,通过自动重试可以减少因单次失败导致的整体业务中断。本篇文章将介绍一款非常优秀的重试框架Fast-Retry。
Fast-Retry是一个高性能任务重试框架,支持百万级别任务的并发重试处理。与主流的Spring-Retry, Guava-Retry等同步重试框架不同,Fast-Retry是一个支持异步重试框架,支持异步任务的重试、超时等待、回调。Spring-Retry, Guava-Retry均无法支持大批量任务的重试,因为会占用过多线程资源导致大量任务在等待处理,随着任务数的增加,系统吞吐量大大降低,性能指数级降低,Fast-Retry的性能是前者的指数倍。
Fast-Retry,Spring-Retry,Guava-Retry性能对比
测试条件
测试线程池: 8个固定线程
单个任务逻辑: 轮询5次,隔2秒重试一次,总耗时10秒
未测预计公式:当我们使用线程池的时候, 一般线程池中 总任务处理耗时 = 任务数/并发度 x 单个任务重试耗时

2. 实战案例
2.1 引入依赖
<dependency><groupId>io.github.burukeyou</groupId><artifactId>fast-retry-all</artifactId><version>0.2.0</version></dependency>
配置开启重试功能
public class SpringbootRetryApplication {}
接下来就可以通过@FastRetry注解配置类或方法。
2.2 基于编程重试
public String process() throws Exception {// 自定义结果重试策略,如果返回结果不是"success"则进行重试RetryResultPolicy<String> resultPolicy = result -> !result.equals("success");FastRetryer<String> retryer = FastRetryBuilder.<String>builder()// 重试次数.attemptMaxTimes(2)// 重试间隔.waitRetryTime(1, TimeUnit.SECONDS)// 发生异常后是否重试.retryIfException(true)// 什么类型的异常进行重试.retryIfExceptionOfType(RuntimeException.class).exceptionRecover(true)// 自定义结果重试策略.resultPolicy(resultPolicy).build();CompletableFuture<String> future = retryer.submit(() -> {int r = new Random().nextInt(10) ;System.out.printf("执行业务方法, 随机值: %d%n", r) ;if (r != 1) {// 抛出异常,也会重试// throw new RuntimeException("错误的参数: " + r) ;return "dead" ;}return "success" ;});return future.get();}
运行结果
成功
执行业务方法, 随机值: 5执行业务方法, 随机值: 4执行业务方法, 随机值: 1结果: success
失败

超过重试次数后抛出异常,并且方法执行的最终结果返回:null。
2.3 基于注解
基于注解方式使用起来与spring-retry差不多。一个注解搞定
(retryWait = (delay = 2),exceptionRecover = false,maxAttempts = 2,retryStrategy = PackRetryPolicy.class)public String business(Long id, String name) {int r = new Random().nextInt(10) ;System.out.printf("执行业务方法, 随机值: %d%n", r) ;if (r != 1) {throw new RuntimeException("错误的参数: " + r) ;}return "success" ;}
自定义方法返回结果重试策略
public class PackRetryPolicy implements RetryResultPolicy<String> {public boolean canRetry(String t) {return !t.equals("success") ;}}
结果重试策略可以有多个。
2.4 异步任务重试
retryWait = @RetryWait(delay = 2),maxAttempts = 2,retryStrategy = PackRetryPolicy.class)public CompletableFuture<String> asyncBusiness(Long id, String name) {return CompletableFuture.supplyAsync(() -> {System.out.println("async 执行业务方法...") ;int r = new Random().nextInt(10) ;if (r != 1) {// throw new RuntimeException("错误的参数: " + r) ;return "1" ;}return "success" ;}) ;}
输出结果
async 执行业务方法...async 执行业务方法...async 执行业务方法...发生错误: com.burukeyou.retry.core.exceptions.FastRetryTimeOutException:The maximum retry count has been exceeded after 2 times. Stop retry
同样的代码,如果换成spring-retry,如下:
// spring-retry的注解public CompletableFuture<String> asyncBusiness(Long id, String name) {// 方法体与上面基本,一样只不过其中抛出的是异常}
输出结果
async 执行业务方法...发生错误: java.lang.RuntimeException: 错误的参数: 3
没有进行重试,说明spring-retry不支持异步任务。
在spring-retry中你可以在注解中配置recover,指定一个恢复的方法(或降级的方法),在fast-retry中没有这样的功能。如下spring-retry示例:
(maxAttempts = 2, recover = "businessRecover")public String business(Long id, String name) {}private String businessRecover(Throwable th, Long id, String name) {}
当重试次数用尽后,将调用我们这里配置的businessRecover方法,同时在该方法中还可以获取具体的异常信息。
以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏
推荐文章
完美!SpringBoot + HTML模板高效生成PDF文档
SpringBoot3必须掌握的5个强大功能,其中JVM优化技巧太厉害了
SpringBoot3.2开始Controller参数验证@Validated新功能
SpringBoot自带Controller接口监控,赶紧用起来
警惕!SpringBoot错误发布事件,造成死锁Deadlock



