springboot 实现重试逻辑

springboot 实现重试逻辑

有时候业务需求,我们需要将一些接口重复的请求,当前端多次调用不太合适的时候。那么我们可以自己调用相关业务。

在什么情况下可以重试

1、远程调用超时、网络突然中断可以重试
2、外部 RPC 调用,如果一次操作失败,可以进行多次重试
3、提高调用成功的可能性

优雅的重试机制要具备几点

无侵入:不改动当前的业务逻辑,对于需要重试的地方,可以很简单的实现
可配置:包括重试次数,重试的间隔时间,是否使用异步方式
通用性:最好是无改动(或者很小改动)的支持绝大部分的场景,拿过来直接可用

导入依赖

	<!--重试机制-->
		<dependency>
			<groupId>org.springframework.retry</groupId>
			<artifactId>spring-retry</artifactId>
			<version>1.3.0</version>
		</dependency>

		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
		</dependency>

注意:这我指定了spring-retry的版本,因为我们使用@Retryable增加recover属性是1.3版本之后,之前是没有这个属性的

启用重试机制 (在启动类中加入 @EnableRetry)

在这里插入图片描述

注解@Retryable
被注解的方法发生异常时会重试

value:指定发生的异常进行重试
include:和value一样,默认空,当exclude也为空时,所有异常都重试
exclude:指定异常不重试,默认空,当include也为空时,所有异常都重试
maxAttemps:重试次数,默认3
backoff:重试补偿机制,默认没有
recover:指定异常调用方法名称
listeners:监听类

注解 @Backoff
delay:指定延迟后重试
multiplier:指定延迟的倍数,比如delay=5000l,multiplier=2时,第一次重试为5秒后,第二次为10秒,第三次为20秒



注解 @Recover
当重试到达指定次数时,被注解的方法将被回调,可以在该方法中进行日志处理。需要注意的是发生的异常和入参类型一致时才会回调

使用完整示例

    /**
     * 重试机制测试
     * @return
     */
    @Override
    @Retryable( recover  ="recoverSdDirectMailBill",value= BusinessException.class,maxAttempts = 3,listeners = {"defaultRetryListener"},backoff = @Backoff(value = 2000, multiplier = 2))
    public void replayMethods()  {
        log.info("数据执行.......");
        int code=0;
        try {
            int i=1/0;
        }catch (Exception e){
            throw  new BusinessException(123,"错误提示");
        }
    }

    @Recover
    public void recoverSdDirectMailBill(BusinessException exception) {
        log.info("数据异常.......{}");
        log.info("异常信息.......{}");
    }
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryListener;
import org.springframework.stereotype.Service;

/**
 * @author lilinchun
 * @date 2022/4/14 0014 14:39
 */
@Service
public class DefaultRetryListener implements RetryListener {

    @Override
    public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
        System.out.println("==前置回调==");
        return true;
    }

    @Override
    public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        System.out.println("==后置回调==");
    }

    @Override
    public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        System.out.println("==执行报错==");
    }
}

执行结果
在这里插入图片描述
注意小细节指定的回调方法必须返回参数是一致的抛出的异常也要是同一个异常

如果不使用指定的回调方法将recover ="recoverSdDirectMailBill"去掉就可以了
如果你想让所有的重试方法都使用同一个回调方法那么就只需要使用它默认的方法就可以了

@Recover
    public void recover(BusinessException exception) {
        log.info("数据异常.......{}");
        log.info("异常信息.......{}");
    }
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱上编程2705

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值