Spring Retry重试机制怎么用?一文搞懂@Retryable与@Recover注解
作者:中文很快乐
分布式系统中网络波动、服务不可用等临时故障频发?Spring Retry重试框架帮你优雅应对!本文详细讲解@Retryable和@Recover注解用法,包括重试次数、退避策略等配置,助你轻松实现方法重试,提升系统健壮性
在分布式系统开发中,网络波动、服务暂时不可用等问题时有发生。
为了提高系统的健壮性,我们需要一种优雅的方式来处理这些临时性故障——这就是Spring Retry的作用!
什么是Spring Retry?
Spring Retry 是Spring生态系统中的一个轻量级重试框架,它提供了声明式的重试机制,让开发者能够轻松地为方法添加重试逻辑,而无需编写复杂的重试代码。
1.核心注解介绍
1.1@Retryable - 重试标记
@Retryable(
value = {Exception.class}, // 指定需要重试的异常类型
maxAttempts = 3, // 最大重试次数(包括第一次调用)
backoff = @Backoff(delay = 1000) // 重试间隔时间(ms)
)
public String callExternalService() {
// 业务逻辑
}
参数说明:
@Retryable 参数详解
- value/include: 需要重试的异常类型
- exclude: 不需要重试的异常类型
- maxAttempts: 最大尝试次数,默认3次
- backoff: 重试等待策略
@Backoff 参数配置
- delay: 固定延迟时间
- multiplier: 延迟倍数(实现指数退避)
- maxDelay: 最大延迟时间
- random: 是否启用随机延迟
1.2@Recover - 回退处理
当重试达到最大次数仍然失败时,可以通过 @Recover 注解指定回退方法:
@Recover
public String recover(Exception ex) {
return "服务调用失败,请稍后再试";
}
@Retryable和@Recover是Spring Framework中的注解,用于支持在方法执行期间发生异常时的重试和恢复操作。
@Retryable注解用于标记方法,在方法执行期间发生异常时进行重试。重试行为可以使用Spring Retry框架提供的默认策略或自定义策略来定义。我们可以指定要重试的异常类型以及最大重试次数和重试间隔等参数。
@Recover注解用于标记一个恢复方法,在最终重试失败后执行该方法,降级处理。恢复方法应尽量具有与重试方法相同的参数和返回类型(提一嘴:两个方法的返回值类型必须相同,捕获异常类型和入参可以不同,后面给出实例),并且应在同一类中声明。如果未指定恢复方法,则重试失败后将抛出最后一次异常。
2.实现步骤
2.1 先加依赖
<!-- 重试机制的依赖-->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<!-- 以下依赖在重试机制中不加会报错-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>2.2 在项目启动类上加注解

3.3 使用
在需要重试的方法上加@Retryable注解:
/**
* @description: 测试重试接口实现类
* @Author yl
* @Date 2024/4/24 16:22
*/
@Service
public class RetryServiceImpl implements RetryService {
private static final Logger logger = LoggerFactory.getLogger(RetryServiceImpl.class);
@Autowired
AccountMapper mapper;
/**
*value:对方法中抛出什么样的异常进行重试机制
*maxAttempts:重试的次数
* backoff:重试的策略:delay为相隔多少时间后重试
*/
@Override
@Retryable(value = BusinessException.class,maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 1.5))
public List<Account> getAllAccountList() {
List<Account> list = mapper.selectAll();
Vector<Account> vector = new Vector<>();
logger.info("获取的数据为:{}",list);
if(true){
logger.info("获取的数据为:{}",list);
throw new BusinessException("开始重试了");
}
return list;
}
/**
* 测试回复方法:@Recover和@Retryable在同一个类中
* @param e 方法名。入参,和@Retryable注解方法一致;此外方法中多一个入参为BusinessException和@Retryable注解的value值一致
* @return 返回参数类型和@Retryable注解方法返回类型一致
*/
@Recover
public List<Account> getAllAccountList(BusinessException e) {
logger.info("在recover方法内,做降级处理");
List<Account> list = new ArrayList<>();
return list;
}
}4.4 测试结果

3.总结
使用要点:
- 启用重试功能: 在配置类上添加 @EnableRetry
- 合理设置重试次数: 避免无限重试导致系统雪崩
- 选择合适的退避策略: 固定间隔 or 指数退避
- 区分异常类型: 对于业务异常不应重试
工作原理:
Spring Retry通过AOP代理实现重试机制:
- 创建代理对象拦截被 @Retryable 标记的方法
- 执行目标方法,捕获指定异常
- 根据配置决定是否重试
- 达到最大重试次数后调用 @Recover 方法
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
