spring-retry详解
- 1.引入依赖
- 2.Retryable基础使用
- 3.Recover使用
- 4.Retryable参数详解
- 5.需要注意
重试机制对于大部分场景来说都是必要的,比如同步调用三方接口,三方接口、信息拉取等网络原因突然不通,有了重试就可以多一些容错机制,异常场景下让系统多一点健壮。
1.引入依赖
需要两个依赖,注意都需要添加,不加aop依赖也不行。注意版本可以不声明使用父工程springboot的版本亦可。
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.Retryable基础使用
启动类增加注解
@EnableRetry
下面是controller入口代码,没啥用就是一个入口
@javax.annotation.Resource
TestService testAction;
@PostMapping("/test")
public void testRetry(){
String s = testAction.testAction(1);
System.out.println("接收返回:"+s);
}
下面是真正的service代码
@Retryable(value = {RuntimeException.class}, maxAttempts = 2, backoff = @Backoff(delay = 1000) )
public String testAction(Integer a){
try {
System.out.println("异常前输出,接收入参:"+a);
int i = a/0;
System.out.println("异常后输出,接收入参:"+a);
} catch (Exception e) {
throw new RuntimeException(e);
}
return "正常返回";
}
调用接口执行结果如下:
可以看到确实在异常场景进行了重试,上面加不加try-catch没有任何影响,加了目的是为了保证抛出的异常是统一的。
这也就达到了目的了,基础使用就是这样,下面一起看看参数该如何设置。
3.Recover使用
上面的重试次数用完以后还是异常会抛出异常,此时异常我们可以选择在调用方(Retryable方法的调用法)继续处理,也可以选择单独加个方法只用来处理异常,这样调用方(Retryable方法的调用法)就可以只专注处理正常逻辑即可。那如何使用呢,注意以下几点:
- Recover注解修饰的方法的入参第一个应该是Retryable方法中抛出的异常
- Recover注解修饰的方法的入参可以将Retryable的入参全部加进来,方便后续处理,但Retryable内部的数据无法传递到Recover,可以通过抽离方法达到公用的目的
- Recover和Retryable修饰的方法必须在同一个类中
- Recover和Retryable修饰的方法返回类型必须一样
- Retryable中无需声明recover的属性,测试后声明了反而不生效
下面是上面Retryable的对应方法
@Recover
public String recover2(RuntimeException e, int code){
System.out.println("回调方法2,入参:"+code);
log.error("异常信息:",e);
return "异常返回";
}
测试结果如下:
可以看到,异常后正常进入到了这个方法,其实就是相当于把这个方法代理下将其放入到Retryable中的方法一起执行,所以需要保持两个方法的的高度一致(主要是出入参,同一个类中)。
4.Retryable参数详解
- recover: 不建议使用,加了以后测试反而找不到异常的回调方法了,不加好使,也有可能是我配置不到位
- value:声明哪些异常触发重试
- include:同上
- exclude:声明异常哪些不触发重试
- label:标记当前的重试,便于追查
- maxAttempts:最大重试次数,默认3
- backoff:重试策略,用来定义重试的间隔与频率
- delay:重试间隔,默认1000ms
- value:同上
- multiplier:间隔乘子,比如delay是1s,该值是2,那么第一次间隔就是两2s,第二次是就是4s
- maxDelay:最大间隔,间隔时间最大的值,用于制约乘子与delay。
5.需要注意
- 注意Retryable不可以使用在controller层
- 同类多个Retryable和Recover,可以用入参、出参来进行自动区分,同时也可以使用不同的异常来区分,比如抛出不同的异常也是可以区分的,因为Recover的入参的异常是确定的。