# SpringBootRetry
SpringBootRetry 自动重试机制
# 1. 说明
引入对应 Jar 包即可使用,SpringBoot 一般 spring-retry
一般都有默认集成,可以不用引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
# 2. 使用
启用注解,放在配置类上,或者 SpringBoot 启动类上都行
@EnableRetry(proxyTargetClass = true)
需要添加 proxyTargetClass = true,才能使接口实现类生效
# 2.1. 直接使用
RetryTemplate retryTemplate = new RetryTemplate();
TimeoutRetryPolicy timeoutRetryPolicy = new TimeoutRetryPolicy();
timeoutRetryPolicy.setTimeout(3000L);
retryTemplate.setRetryPolicy(timeoutRetryPolicy);
String result = retryTemplate.execute(retryContext -> {
// 处理业务结束,根据结果判断,处理失败抛出 RetryableException 异常即可自动重试
if (Boolean.FALSE.equals(param)) {
throw new RetryableException();
}
return null;
}, recoveryCallback -> {
// 超过最大重试次数方法
return null;
});
# 2.2. 简单封装
使用注解更加方便
/**
* 重试业务类型
*
* @author wliduo[i@dolyw.com]
* @date 2022/4/24 10:55
*/
@Getter
@AllArgsConstructor
public enum RetryTypeEnum {
/**
* 重试业务类型
*/
RT0001("RT0001", "上传重试"),
/**
* XXXX-重试业务类型
*/
XXXXXX("XXXXXX", "XXXXXX");
private String code;
private String name;
}
import cn.hutool.core.exceptions.ExceptionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
/**
* 常规重试业务处理,实现对应的重试方法即可,熔断统一写在retryableRecover方法
*
* @author wliduo[i@dolyw.com]
* @date 2022/12/28 15:08
*/
@Service
public class Retryable {
private static final Logger logger = LoggerFactory.getLogger(Retryable.class);
/**
* 示例重试方法
*
* maxAttempts: 最大重试次数,设置为5次的话,开始执行的一次失败后会再重试4次
* delay: 延迟多少秒重试,每次失败后延时多久执行
* multiplier: 延迟因子,默认为1,需要递增延迟才设置
*
* 如果(delay = 2000L, multiplier = 2)
* 则第一次重试为2秒,第二次为2*2=4秒,第三次为4*2=8秒,第四次为8*2=16秒
*
* @param retryTypeEnum
* @param param
* @return java.lang.String
* @throws
* @author wliduo[i@dolyw.com]
* @date 2022/12/28 15:19
*/
@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 5000L, multiplier = 1))
public Object example(RetryTypeEnum retryTypeEnum, Object param) {
Object result = param;
// 处理业务结束,根据结果判断,处理失败抛出 RetryableException 异常即可自动重试
if (Boolean.FALSE.equals(result)) {
throw new RetryableException();
}
return result;
}
/**
* 超过最大重试次数熔断返回
*
* @param e
* @param retryTypeEnum
* @return java.lang.Object
* @throws
* @author wliduo[i@dolyw.com]
* @date 2022/12/28 15:10
*/
@Recover
public Object retryableRecover(Exception e, RetryTypeEnum retryTypeEnum) {
logger.error("重试业务处理超过最大重试次数熔断返回,异常:{}", ExceptionUtil.stacktraceToOneLineString(e));
// 根据对应重试业务返回异常结果
if (RetryTypeEnum.RT0001.equals(retryTypeEnum)) {
return "处理失败";
}
return null;
}
}
参考