文章目录
- 前言
- 一、幂等性是重试的前提
- 二、使用步骤
- 1.引入依赖
- 2.启动类或配置类上添加@EnableRetry,启用retry框架
- 3.创建一个要重试的方法
- 4.自定义一个retry监听
- 5.创建一个测试类
- 总结
前言
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("执行恢复");
}
}
- value 哪些异常要重试
- maxAttempts 最大重试次数,包括请求的那次,默认就是3
- listeners 监听类的名称,可以是多个
- 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框架开始重试执行,然后三次失败后,执行了恢复方法;
- 当在重试过程中,开始重试,每次报错,到最后一次重试关闭,每次都可以监听到,并可以在监听中自定义参数,并读取到;