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

2024-01-07 19:29:25


前言

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


一、幂等性是重试的前提

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

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

如何保证接口幂等性

二、使用步骤

1.引入依赖

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

 <dependency>
     <groupId>org.springframework.retry</groupId>
      <artifactId>spring-retry</artifactId>
  </dependency>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
  </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} 注解,加在接口方法和实现类方法上都能实现相同的重试功能
     * <p>
     * 区别如下:
     * <li>加在接口方法: 那么所有实现类都是统一的行为,都重试</li>
     * <li>加在实现类方法上: 那么只有该类会执行重试</li>
     * <p/>
     */
    @SneakyThrows
    @Override
    @Retryable(value = Exception.class, maxAttempts = 3, listeners = {"retryListenerDemo"})
    public void exceptionMethod() {
        System.out.println("开始执行");
        throw new Exception("抛出异常");
    }

    /**
     * 重试失败后,此方法用于执行恢复
     * <p>此方法必须为void 且需要与重试方法{@link RetryServiceImpl#exceptionMethod}所在同一个类中</p>
     */
    @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();
    }
}

打印结果如下:
运行结果


总结

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

文章来源:https://blog.csdn.net/qq_32419139/article/details/134947798
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。