Spring Retry 是一个用于在 Spring 应用中实现重试机制的库。它提供了一种方便的方式来处理可能因各种原因失败的操作,并在失败时进行重试。一般可以用于: rpc重试, 数据同步等类似问题;
确保操作的幂等性是使用Spring Retry的重要前提之一,可以避免系统在面对重复请求或操作时产生不一致的状态或结果。
幂等性是指: 同一个资源的多个请求在业务逻辑上具有相同的结果。
由于是通过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>
代码如下(示例):
@SpringBootApplication
@MapperScan("com.auth.token.dao*")
@EnableRetry
public class TokenApplication {
public static void main(String[] args) {
SpringApplication.run(TokenApplication.class, args);
}
}
代码如下(示例):
@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 可以设置重试间隔
代码如下(示例):
/**
* 自定义的 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>>>报错了");
}
}
代码如下(示例):
@SpringBootTest
class RetryServiceTest {
@Autowired
RetryService retryService;
@Test
void exceptionMethod() {
retryService.exceptionMethod();
}
}
打印结果如下: