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

迁移至Spring Core重试模块,是否有Sleeper Bean等效实现?

Spring Core重试模块替换无休眠Sleeper的实现方案

Spring Core重试模块没有提供开箱即用的无休眠Sleeper实现,但可以通过自定义退避策略来覆盖默认的Thread.sleep行为,既加快测试速度,又能统计预期的休眠耗时。

  • 核心思路:默认的FixedBackOffPolicy等退避策略内部会调用Thread.sleep,我们可以自定义BackOffPolicy实现,在backOff方法中跳过休眠逻辑,同时记录原本应该休眠的时长。

具体实现步骤

1. 自定义无休眠退避策略

实现BackOffPolicy接口,跳过休眠并统计预期耗时:

import org.springframework.retry.backoff.BackOffContext;
import org.springframework.retry.backoff.BackOffPolicy;
import java.util.concurrent.atomic.AtomicLong;

public class NoSleepBackOffPolicy implements BackOffPolicy {
    private final AtomicLong totalIntendedSleepTime = new AtomicLong(0);
    private long fixedSleepDuration = 1000; // 模拟固定退避时长

    @Override
    public BackOffContext start(RetryContext context) {
        return new NoSleepBackOffContext();
    }

    @Override
    public void backOff(BackOffContext backOffContext) {
        // 不执行Thread.sleep,直接累加预期休眠时长
        totalIntendedSleepTime.addAndGet(fixedSleepDuration);
    }

    // 提供获取总预期耗时的方法,用于断言
    public long getTotalIntendedSleepTime() {
        return totalIntendedSleepTime.get();
    }

    // 可选:支持动态设置退避时长
    public void setFixedSleepDuration(long fixedSleepDuration) {
        this.fixedSleepDuration = fixedSleepDuration;
    }

    private static class NoSleepBackOffContext implements BackOffContext {}
}

2. 测试中配置RetryTemplate

在集成测试里,给RetryTemplate注入自定义的退避策略:

import org.junit.jupiter.api.Test;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class RetryTest {

    @Test
    void testRetryWithoutSleep() {
        NoSleepBackOffPolicy noSleepBackOffPolicy = new NoSleepBackOffPolicy();
        noSleepBackOffPolicy.setFixedSleepDuration(1000);

        RetryTemplate retryTemplate = new RetryTemplate();

        // 设置重试次数
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(3); // 会触发2次退避
        retryTemplate.setRetryPolicy(retryPolicy);

        // 替换为自定义无休眠退避策略
        retryTemplate.setBackOffPolicy(noSleepBackOffPolicy);

        // 执行带重试的业务逻辑
        try {
            retryTemplate.execute((RetryCallback<Void, RuntimeException>) context -> {
                throw new RuntimeException("模拟重试触发场景");
            });
        } catch (RuntimeException ignored) {
            // 忽略重试最终抛出的异常,专注断言耗时
        }

        // 断言总预期休眠时长:2次退避 × 1000ms = 2000ms
        assertEquals(2000, noSleepBackOffPolicy.getTotalIntendedSleepTime());
    }
}

3. 适配指数退避场景

如果你的业务用了指数退避,也可以继承ExponentialBackOffPolicy重写backOff方法:

import org.springframework.retry.backoff.ExponentialBackOffContext;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import java.util.concurrent.atomic.AtomicLong;

public class NoSleepExponentialBackOffPolicy extends ExponentialBackOffPolicy {
    private final AtomicLong totalIntendedSleepTime = new AtomicLong(0);

    @Override
    public void backOff(BackOffContext backOffContext) {
        ExponentialBackOffContext context = (ExponentialBackOffContext) backOffContext;
        long intendedSleepTime = getSleepAndIncrement(context);
        totalIntendedSleepTime.addAndGet(intendedSleepTime);
        // 跳过父类的Thread.sleep逻辑
    }

    public long getTotalIntendedSleepTime() {
        return totalIntendedSleepTime.get();
    }
}

内容的提问来源于stack exchange,提问作者whistling_marmot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 13:33:15