# 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;
    }
}

参考

上次更新时间: 2023-12-15 03:14:55