【Spring插件】Spring快速实现接口重试功能

需求

在应用程序中,由于一些网络等不可预知的问题,我们的程序或者接口会失败,比如调用一个第三方的接口获取数据失败了,这时就需要重试机制,比如延时 3S 后重试、间隔不断增加重试等,而这些机制完全不需要你自己去实现,全部交给 Spring Retry 吧。

使用

1. 在 pom 文件中添加相应的依赖
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.2.2.RELEASE</version>
</dependency>

最新版本可以在 Maven Central 找到 Spring Retry 使用 AOP 实现,所以必须要有 spring-aspects 依赖,

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
</dependency>

2. 在启动类或者配置类上添加注解 @EnableRetry

配置类

@Configuration
@EnableRetry
public class AppConfig { ... }

启动类

@SpringBootApplication
@EnableRetry
public class Application

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(maxAttempts = 3, backoff = @Backoff(value = 3000, multiplier = 1.5))
public Customer getCustomer(String customerId) {
  if (true) {
   JSONArray data = retObj.getJSONArray("data");
   if (data != null && !data.isEmpty()) {
    return data.toJavaList(Customer.class).get(0);
   }
  } else {
   log.error("异常,{}", customerId);
   throw new RuntimeException("获数据失败");
  }
  return null;
}

@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;multiplier(指定延迟倍数)默认为 0,表示固定暂停 1 秒后进行重试,如果把 multiplier 设置为 1.5,则第一次重试为 2 秒,第二次为 3 秒,第三次为 4.5 秒。

4. 可以在指定方法上标记 @Recover 来开启重试失败后调用的方法 (注意, 需跟重处理方法在同一个类中)

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

5. 采坑提示
  • 1、由于 retry 用到了 aspect 增强,所有会有 aspect 的坑,就是方法内部调用,会使 aspect 增强失效,那么 retry 当然也会失效。参考改链接

public class demo {
    public void A() {
        B();
    }

    //这里B不会执行
    @Retryable(Exception.class)
    public void B() {
        throw new RuntimeException("retry...");
    }
}

  • 2、重试机制,不能在接口实现类里面写。所以要做重试,必须单独写个 service。

  • 3、maxAttemps 参数解释的是说重试次数,但是我再打断点的时候发现这个 = 1 时,方法一共只执行了一次。

参考文献

  • @Retryable(spring 的重试机制) https://juejin.im/post/5d97630ef265da5bad405134

  • @Retryable(spring 的重试机制) https://blog.csdn.net/qq_20989105/article/details/80003087

  • https://www.baeldung.com/spring-retry


作者:jieniyimiao

来源链接:

https://blog.csdn.net/u013467442/article/details/105746620

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值