spring retry 异常重试

SpringRetry 调用方法出现异常后进行重试。

场景:后端进行远程调用,可能会出现网络波动而导致远程调用失败,需要在调用失败后进行重试,重试间隔为2秒,重试次数为3次。通过spring retry就能够完美的实现

1 引入依赖

<!-- retry底层通过aop实现,必须引入aop依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<!-- spring retry依赖 -->
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

2. 代码

1 通过 @EnableRetry 开启retry功能

@EnableRetry
@SpringBootApplication
public class WebTestApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebTestApplication.class, args);
    }
}

2 在对应的方法上新增@Retryable注解

@Slf4j
@Service
public class TestService {
	
    /**
    @Retryable在进行重试的时候是同步的(controller只有在重试3次后才返回结果)
    如果需要支持异步,需要配合@Asyc实现
    */
    @Async
    @Retryable(value = {Throwable.class},maxAttempts = 3,backoff = @Backoff(value = 2000,multiplier = 2))
    public void retryMethod(Integer param) {
        int i = new Random().nextInt(param);
        log.info("随机生成的数:{}", i);

        if (1 == i) {
            log.info("为1,返回true.");
        } else if (i > 5) {
            log.info("大于5,抛出参数异常.");
            throw new IllegalArgumentException("大于5,抛出参数异常."+i);
        } else if ( i> 10) {
            log.info("大于10,直接返回false");
        } else {
            //为其他
            log.info("小于5,抛出自定义异常.");
            throw new RemoteAccessException("小于5,抛出自定义异常."+i);
        }
    }

    /**
    加了@Recover的方法会兜底方法,在重试失败后会进行调用
    一个类内可以有多个@Recover方法,选取时根据异常进行匹配,和@ExceptionHandler类似
    */
    @Recover
    public void recover1(Throwable e){
        log.error("重试方法出现异常--->{}",e.getMessage());
    }

}

3 @RetryAble 常用参数

public @interface Retryable {

	/**
	 * 一般不用
	 */
	String recover() default "";

	/**
	 * 一般不用
	 */
	String interceptor() default "";

	/**
	 * 当跑出对应异常时进行重试
	 */
	Class<? extends Throwable>[] value() default {};

	/**
	 * 和value一样
	 */
	Class<? extends Throwable>[] include() default {};

	/**
	 * 忽略某些异常
	 */
	Class<? extends Throwable>[] exclude() default {};

	/**
	 * 一般不用
	 */
	String label() default "";

	/**
	 * 一般不用
	 */
	boolean stateful() default false;

	/**
	 * 重试次数,默认为3
	 */
	int maxAttempts() default 3;

	/**
	 * 返回重试次数的表达式,一般不用
	 */
	String maxAttemptsExpression() default "";

	/**
	 * 配置重试的细节,如重试间隔时间等
	 */
	Backoff backoff() default @Backoff();

	/**
	 * 
	 */
	String exceptionExpression() default "";

	/**
	 * 
	 */
	String[] listeners() default {};

}

Backoff

public @interface Backoff {

	// 与delay效果等价,失败后等待多少ms重试下一次
	long value() default 1000;

	// 与valuey效果等价,失败后等待多少ms重试下一次
	long delay() default 0;

	// 重试等待的最大时间与delay配合使用,以下是一些结论
	// 1. 如果@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000,maxDelay = 9000)) 则本例等待时间是1000~9000之间随机
	// 2. 如果配合multiplier使用时,maxDelay<delay,@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000,maxDelay = 900,multiplier=1.5)),则本例子等待时间是1000~30000之间,也就是在multiplier配置的情况下,maxDelay非0,且maxDelay<delay,则maxDelay=30s
	long maxDelay() default 0;
	
	// 可以指数增长重试间隔
	double multiplier() default 0;


	String delayExpression() default "";


	String maxDelayExpression() default "";


	String multiplierExpression() default "";

	// 在使用multiplier时有效,配置为true,每次延迟的时间会有一定的随机
	boolean random() default false;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值