You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 00:45:25