目录

  • 依赖
  • 启动类
  • 声明式重试



 

发送消息失败、远程服务调用失败、获取锁失败…发生异常后有时需要自动重试,常用的重试框架有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。