在项目开发过程中,经常会有这样的情况:第一次执行一个操作不成功,考虑到可能是网络原因造成,就多执行几次操作,直到得到想要的结果为止,这就是重试机制。spring支持重试机制
使用
1、在pom文件中添加依赖
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
Spring Retry使用AOP实现,所以必须要有spring-aspects依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
2、在启动类上加@EnableRetry
注解,表示启用重试机制
@SpringBootApplication
@EnableRetry
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
3、在需要重试的方法上添加注解@Retryable
@Service
public class DemoService {
@Retryable(value= {Exception.class},maxAttempts = 3)
public void call() throws Exception {
System.out.println("do something...");
throw new Exception("RPC调用异常");
}
@Recover
public void recover(RemoteAccessException e) {
System.out.println(e.getMessage());
}
}
@Retryable(value = Exception.class,maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 1.5))
value值表示当哪些异常的时候触发重试,maxAttempts表示最大重试次数默认为3,delay表示重试的延迟时间,multiplier表示上一次延时时间是这一次的倍数。
@Retryable被注解的方法发生异常时会重试
@Retryable注解中的参数说明:
maxAttempts :最大重试次数,默认为3,如果要设置的重试次数为3,可以不写;(包括第一次调用)
value:重试的触发机制,抛出指定异常才会重试
include:和value一样,默认为空,当exclude也为空时,所有异常都重试
exclude:指定不处理的异常,默认空,当include也为空时,所有异常都重试
backoff:重试等待策略,默认使用@Backoff@Backoff的value默认为1000L,我们设置为2000L。
@Backoff重试补偿机制,默认没有
@Backoff注解中的参数说明:
value:隔多少毫秒后重试,默认为1000L,我们设置为3000L;
delay:重试的间隔时间,和value一样,但是默认为0;
maxDelay:重试次数之间的最大时间间隔,默认为0,如果小于delay的设置,则默认为30000L
multiplier:delay时间的间隔倍数(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。
4、可以在指定方法上标记@Recover来开启重试失败后调用的方法(注意,需跟重处理方法在同一个类中)
@Recover
注解,当重试次数达到设置的次数的时候,还是失败抛出异常,执行的回调函数。(可以在该方法中进行日志处理。需要注意的是发生的异常和入参类型一致时才会回调)
注意点
1、由于aspect机制,不要在同一个类中调用加上@Retryable注解的方法,会使aspect增强失效,那么retry当然也会失效
public class demo {
public void A() {
B();
}
@Retryable(Exception.class)
public void B() {
throw new RuntimeException("retry...");
}
}
2、在实际项目中,如果是为了避免网络波动而加上的重试机制,在重试的时候需要加上延迟,重试时间间隔设置大一点,这样效果可能好一点
3、重试机制,不能在接口实现类里面写。所以要做重试,必须单独写个service
参考文献
spring的@Retryable重试机制
https://blog.csdn.net/qq_28165595/article/details/102635534
JAVA如何优雅的重试?@Retryable(spring的重试机制)
https://jieniyimiao.blog.csdn.net/article/details/105746620
Springboot整合Spring Retry实现重试机制
https://blog.csdn.net/huanongying123/article/details/104417712
springboot 整合retry(重试机制)
https://www.jianshu.com/p/314059943f1c?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation