SpringBoot中重试框架——Spring-retry与Guava-Retry

在SpringBoot项目的开发中,我们会有一种场景,就是调用接口或方法失败后需要进行重试。此时我们可以使用Spring-retry框架进行方法重试。

Spring-retry使用方法

引入依赖

		
			org.springframework.retry
			spring-retry
		

开启重试功能

在SpringBoot项目的主启动类上添加@EnableRetry注解。

SpringBoot中重试框架——Spring-retry与Guava-Retry_第1张图片

使用方式

在接口或是方法上添加@Retryable注解表示当前方法如果出现异常需要进行重试。

SpringBoot中重试框架——Spring-retry与Guava-Retry_第2张图片

 @Retryable注解中的属性

value:指定异常类型,只有抛出了此异常才会进行重试。

include:与value作用相同。

exclude:指定哪些异常不需要处理。

maxAttempts:最大重试次数。

backoff:重试等待策略,这个属性比较特殊,他的值是@Backoff注解,我们根据这个注解的参数去配置等待策略

-----------------------------------------------------------------------------------------------------------------------

@Backoff注解属性

value:延迟属性,单位是毫秒,默认1秒钟重试一次。

multiplier:延迟倍数,通过value属性与此属性相乘获取第一次的重试时间,重试后再次乘以此参数获取下一次的重试时间。

如果重试失败不想继续重试了,我们可以通过@Recover注解创建一个重试失败的处理方法。

SpringBoot中重试框架——Spring-retry与Guava-Retry_第3张图片

 我们使用此框架一定要注意以下几点,否则直接上生产就报错给你看

1. 回调方法必须与重试方法在同一个类中

2. 多个回调方法返回值不能相同,也就是说同一个类中不能有两个String类型的回调方法,否则调用回调方法时会报异常。

3. 回调方法可以添加异常参数,表示我们捕获到的异常,也可以选择无参

4. 回调方法最后的返回值会直接作为重试方法的返回值

5. 捕获的异常相当于被try...catch...了,回调方法就是其中catch那部分(这个意思就是说异常信息需要自己处理,不会直接打印了)。

其实retry框架也有很多局限性,比如他只支持对于异常的捕获,并且重试失败之后调用回调方法只能传递异常信息,无法传递其他信息

相比于retry框架,Guava-Retry框架则更加灵活。

Guava-Retry使用方法

引入依赖

		
			com.github.rholder
			guava-retrying
			2.0.0
		

使用方式

这个框架大部分常用的内容都在这个类里面了。

package com.project.springtest.controller;

import com.github.rholder.retry.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("api/exam")
public class ExamController {

    @Autowired
    private MyService myService;

    // 注入应用上下文,是为了通过IOC容器去获取当前类的Bean对象
    @Autowired
    private ApplicationContext applicationContext;

    // 声明一个重试者对象(泛型的声明一般使用要重试的方法返回值)
    public static Retryer retryer;

    static {
        // 创建一个重试者对象,进行重试策略配置
        retryer = RetryerBuilder. newBuilder() // 此处泛型与声明的重试者对象泛型一致
                .retryIfExceptionOfType(ClassNotFoundException.class)    // 对指定异常进行重试
                .retryIfException()   // 对所有异常进行重试
                .retryIfResult(res-> res == 1)    // 设置根据结果,如果相比结果为true则进行重试(lambda表达式res类型与newBuilder前的泛型一致)
                .retryIfRuntimeException()  // 对所有运行时异常进行重试
                .withWaitStrategy(WaitStrategies.fixedWait(3, TimeUnit.SECONDS)) // 设置重试等待间隔时间
                .withStopStrategy(StopStrategies.stopAfterAttempt(3)) // 设置最大重试次数
                .build();
    }

    @GetMapping("/exam1")
    public String initiateApproveProcess() {
        System.out.println("执行了此方法");
        try {
            // 此方法直接调用我们需要重试的方法,可以接收返回值
            // 由于我们调用的是本类的方法,但并不想去新创建对象,所以我们在IOC容器中去获取Bean对象
            // 通过BeanName去获取Bean,名字默认首字母小写
            Integer result = ExamController.retryer.call(() -> ((ExamController) applicationContext.getBean("examController")).test());
        } catch (IllegalArgumentException | RetryException | ExecutionException e) {
            // 如果重试达到最大次数还没有成功返回则会抛出RetryException异常,我们可以将其捕获并进行处理
            System.out.println(e.getMessage());
        }
        return "OK";
    }

    /**
     * 需要重试的方法
     * @return 返回数字
     */
    public Integer test() {
        System.out.println("重试");
        return 23;
    }
}

SpringBoot中的重试框架就到这里了,在工作中可以根据具体情况进行选择。希望能够对小伙伴们有帮助。

你可能感兴趣的:(Web后端组件,spring,boot)