2021-03-31 Springboot 整合 retry重试机制

在项目开发过程中,经常会有这样的情况:第一次执行一个操作不成功,考虑到可能是网络原因造成,就多执行几次操作,直到得到想要的结果为止,这就是重试机制。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

猜你喜欢

转载自blog.csdn.net/fggsgnhz/article/details/115343155