目录
- 依赖
- 启动类
- 声明式重试
发送消息失败、远程服务调用失败、获取锁失败…发生异常后有时需要自动重试,常用的重试框架有2个
- spring-retry:社区活跃,能与spring体系无缝整合,推荐
- guava-retrying:已经多年没维护了
spring-retry 和spring的事务管理一样,有声明式(注解)、编程式(自行写代码)2种使用方式,更推荐使用声明式,不侵入原有业务逻辑。声明式是基于aop实现的,还需要引入aop相关依赖,同样具有aop相关的坑,比如
- 不支持调用当前类中的其它方法
- 方法内不能 try catch 吞掉异常,需要往外抛才能触发重试
依赖
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
启动类
启用 spring-retry
@EnableRetry
声明式重试
@Service
public class UserServiceImpl implements UserService {
@Retryable
// @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier = 1.5))
public UserPo getUserInfo(Long userId, String username) {
}
@Recover
public UserPo getUserInfoRecover(Exception e, Long userId, String username) {
}
}
@Retryable 抛出指定异常时自动重试,如果达到最大重试次数还是不行,会自动调用当前类中 @Recover 标注的形参表、返回值类型相同的方法兜底。
@Recover 方法可选,返回值类型和@Retryable方法保持一致,第一个参数和@Retryable指定的异常类型保持一致,后续参数和@Retryable方法形参表保持一致(末尾的参数可以省略,但参数顺序不能乱)。
@Retryable 常用属性
- value、include、exclude:指定要处理的异常类型,可搭配使用
- maxAttempts:最大尝试次数,默认3。注意是尝试,不是重试,第一次调用就算1次尝试,即默认为1次初始调用 + 2次重试
- backoff:重试时间间隔配置
- delay:延迟时间(ms,默认为0),delay不为0时才取delay的值,否则取value(默认1000ms)的值。
- multiplier:间隔倍数,为正数时才有效,eg.delay=5s、multiplier=3,则初次调用失败后间隔 5s 进行第1次重试,第1次重试失败后间隔 5s * 3 = 15s 进行第2次重试,第2次重试失败后间隔 15s * 3 = 45s 后再次重试,每次都是在前一次间隔时间的基础上*multiplier,默认为0 固定重试间隔时间。
- maxDelay:最大延迟时间,重试间隔超过maxDelay时取maxDelay,默认30s。