如何用Spring Retry实现1、5、10、30、60秒间隔的5次重试?
问题解决:Spring Retry实现自定义固定序列重试间隔
问题背景
某方法在12:00:00调用失败,需在12:00:01、12:00:06、12:00:16、12:00:46、12:01:46这五个时间点重试(对应间隔依次为1s、5s、10s、30s、60s),原代码因@Backoff注解使用错误导致报错。
原代码错误原因
@Backoff注解的custom参数要求传入BackOffPolicy的实现类(类字面值),而非运行时注入的Bean实例——注解是编译期处理的,无法引用动态注入的对象。
解决方案
1. 实现自定义固定序列退避策略
创建继承StatelessBackOffPolicy的自定义策略类,按指定间隔序列执行退避:
import org.springframework.retry.backoff.BackOffContext; import org.springframework.retry.backoff.StatelessBackOffPolicy; import org.springframework.stereotype.Component; @Component public class FixedSequenceBackOffPolicy extends StatelessBackOffPolicy { // 对应5次重试的间隔(毫秒):1s、5s、10s、30s、60s private final long[] backOffIntervals = {1000L, 5000L, 10000L, 30000L, 60000L}; @Override protected void doBackOff(BackOffContext context) throws InterruptedException { RetryCountBackOffContext retryContext = (RetryCountBackOffContext) context; int retryCount = retryContext.getRetryCount(); if (retryCount < backOffIntervals.length) { Thread.sleep(backOffIntervals[retryCount]); } } @Override public BackOffContext start() { return new RetryCountBackOffContext(0); } // 自定义上下文,记录当前重试次数 private static class RetryCountBackOffContext implements BackOffContext { private int retryCount; public RetryCountBackOffContext(int retryCount) { this.retryCount = retryCount; } public int getRetryCount() { return retryCount++; } } }
2. 修改@Retryable注解配置
将自定义策略类传入@Backoff的custom参数,同时设置正确的maxAttempts(原调用1次+5次重试=6次):
import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; import java.time.LocalTime; import java.util.ArrayList; import java.util.List; @Service public class YourService { @Retryable( value = Exception.class, maxAttempts = 6, backoff = @Backoff(custom = FixedSequenceBackOffPolicy.class) ) public ResponseResult<List<String>> get() { System.out.println("start: " + LocalTime.now()); // 模拟业务逻辑,如需测试重试可抛出异常 // throw new RuntimeException("调用失败"); ArrayList<String> list = new ArrayList<>(List.of("A", "B", "C")); System.out.println("done"); return ResponseResult.success(list); } }
3. 确保Spring Retry启用
在Spring Boot启动类或配置类上添加@EnableRetry注解,开启重试功能:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.retry.annotation.EnableRetry; @SpringBootApplication @EnableRetry public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
关键说明
StatelessBackOffPolicy是无状态退避策略,适合不需要保存上下文状态的场景;若需要状态可使用StatefulBackOffPolicy。- 若重试次数超过间隔数组长度,当前逻辑会直接跳过退避,可根据需求添加边界处理(如复用最后一个间隔值)。
内容的提问来源于stack exchange,提问作者Pip
相关产品推荐
相关产品推荐

