优雅永不过时: spring-retry 重试框架

文章目录

  • 前言
  • 一、幂等性是重试的前提
  • 二、使用步骤
    • 1.引入依赖
    • 2.启动类或配置类上添加@EnableRetry,启用retry框架
    • 3.创建一个要重试的方法
    • 4.自定义一个retry监听
    • 5.创建一个测试类
  • 总结


前言

Spring Retry 是一个用于在 Spring 应用中实现重试机制的库。它提供了一种方便的方式来处理可能因各种原因失败的操作,并在失败时进行重试。一般可以用于: rpc重试, 数据同步等类似问题;


一、幂等性是重试的前提

确保操作的幂等性是使用Spring Retry的重要前提之一,可以避免系统在面对重复请求或操作时产生不一致的状态或结果。

幂等性是指: 同一个资源的多个请求在业务逻辑上具有相同的结果。

如何保证接口幂等性

二、使用步骤

1.引入依赖

由于是通过aop实现的,所以除了引入retry之外,还要引入aop

 <dependency>
     <groupId>org.springframework.retrygroupId>
      <artifactId>spring-retryartifactId>
  dependency>
  <dependency>
      <groupId>org.springframework.bootgroupId>
      <artifactId>spring-boot-starter-aopartifactId>
  dependency>

2.启动类或配置类上添加@EnableRetry,启用retry框架

代码如下(示例):

@SpringBootApplication
@MapperScan("com.auth.token.dao*")
@EnableRetry
public class TokenApplication {
    public static void main(String[] args) {
        SpringApplication.run(TokenApplication.class, args);
    }
}

3.创建一个要重试的方法

代码如下(示例):

@Service
public class RetryServiceImpl implements RetryService {


    /**
     * {@link Retryable} 注解,加在接口方法和实现类方法上都能实现相同的重试功能
     * 

* 区别如下: *

  • 加在接口方法: 那么所有实现类都是统一的行为,都重试
  • *
  • 加在实现类方法上: 那么只有该类会执行重试
  • *

    */ @SneakyThrows @Override @Retryable(value = Exception.class, maxAttempts = 3, listeners = {"retryListenerDemo"}) public void exceptionMethod() { System.out.println("开始执行"); throw new Exception("抛出异常"); } /** * 重试失败后,此方法用于执行恢复 *

    此方法必须为void 且需要与重试方法{@link RetryServiceImpl#exceptionMethod}所在同一个类中

    */
    @Recover public void recoverMethod() { System.out.println("执行恢复"); } }
    1. value 哪些异常要重试
    2. maxAttempts 最大重试次数,包括请求的那次,默认就是3
    3. listeners 监听类的名称,可以是多个
    4. backoff 可以设置重试间隔

    4.自定义一个retry监听

    代码如下(示例):

    /**
     * 自定义的 retry-listener
     */
    @Component
    public class RetryListenerDemo implements RetryListener {
    
        @Override
        public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
            System.out.println(context.getRetryCount());
            context.setAttribute("a", "我是Retry上下文中存入的数据");
            System.out.println("listener>>>开始监听");
    //        return false; // 否决整个重试
            return true; // 继续重试
        }
    
        @Override
        public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
            System.out.println(context.getAttribute("a"));
            System.out.println("listener>>>关闭");
        }
    
        @Override
        public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
            System.out.println("listener>>>报错了");
        }
    }
    

    5.创建一个测试类

    代码如下(示例):

    @SpringBootTest
    class RetryServiceTest {
    
        @Autowired
        RetryService retryService;
    
        @Test
        void exceptionMethod() {
            retryService.exceptionMethod();
        }
    }
    

    打印结果如下:
    优雅永不过时: spring-retry 重试框架_第1张图片


    总结

    • 可以看到,当抛出异常后,retry框架开始重试执行,然后三次失败后,执行了恢复方法;
    • 当在重试过程中,开始重试,每次报错,到最后一次重试关闭,每次都可以监听到,并可以在监听中自定义参数,并读取到;

    你可能感兴趣的:(springboot,spring,python,java)