调用重试
概述
Spring Retry用于解决分布式系统中的网络抖动、连接超时、服务端不可用等网络问题,通过重试机制来保证服务的可用性。在macula中,我们使用了Spring Retry来实现重试机制,通过配置retry策略来达到重试的目的。
组件坐标
<dependency>
<groupId>dev.macula.boot</groupId>
<artifactId>macula-boot-starter-retry</artifactId>
<version>${macula.version}</version>
</dependency>
使用配置
核心功能
@Retryable注解
需要在重试的代码中加入重试注解@Retryable
@Service
@Slf4j
public class RetryRequestService {
@Autowired
private OtherSystemSpi otherSystemSpi;
@Retryable(value = RuntimeException.class, maxAttempts = 5, backoff = @Backoff(delay = 100))
public String request(String param) {
double random = Math.random();
log.info("请求进来了,随机值为:" + random);
if (random > 0.1) {
throw new RuntimeException("超时");
}
return otherSystemSpi.request(param);
}
}
当然,我们这里写了个调皮的逻辑来模拟超时。如果随机值大于0.1则抛出一个RuntimeException异常。每次请求进来时都会输出日志。
我来解释一下@Retryable注解中的信息。
- value:指定发生的异常进行重试
- include:和value一样,默认空,当exclude也为空时,所有异常都重试
- exclude:指定异常不重试,默认空,当include也为空时,所有异常都重试
- maxAttemps:重试次数,默认3
- backoff:重试补偿机制,默认没有
@Backoff注解
- delay:指定延迟后重试
- multiplier:指定延迟的倍数,比如delay=5000l,multiplier=2时,第一次重试为5秒后,第二次为10秒,第三次为20秒
@Recover注解
有时,在达到最大重试次数后,我们可能希望执行一些特定的逻辑来处理重试失败的情况。@Recover注解可以用于定义在重试失败时执行的备用方法。
@Retryable(maxAttempts = 3, value = {MyCustomException.class})
public void performSomeOperation() {
// 重试逻辑需要执行的操作
}
@Recover
public void handleRecovery(MyCustomException exception) {
// 备用逻辑,用于处理重试失败的情况
}
在上面的示例中,当达到最大重试次数后,handleRecovery()方法将被调用,并且传递给它的参数是触发重试失败的异常对象。
回调方法的参数可以可选地包括抛出的异常和(可选)传递给原始可重试方法的参数。
回调方法注意事项:
- 方法的返回值必须与@Retryable方法一致
- 方法的第一个参数,必须是Throwable类型的,建议是与@Retryable配置的异常一致
- 回调方法与重试方法写在同一个类里面
依赖引入
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
</dependencies>
版权说明
- spring-retry:https://github.com/spring-projects/spring-retry/blob/master/LICENSE