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

Spring Webflux中如何利用返回的retryTime配置RetryBackoffSpec动态退避

动态调整Reactor重试退避时长(基于服务器返回的retryTime)

你的现有代码使用固定退避时长的重试策略,但遇到服务器返回106响应时,需要改用服务器指定的retryTime来计算退避时长,同时保留抖动、重试次数等原有配置。可以通过以下步骤实现:

1. 定义自定义异常传递重试时长

创建一个异常类,用来携带服务器返回的retryTime,让重试逻辑能获取这个值:

public class ServerRetryException extends RuntimeException {
    private final long retryTimeSeconds;

    public ServerRetryException(long retryTimeSeconds) {
        this.retryTimeSeconds = retryTimeSeconds;
    }

    public long getRetryTimeSeconds() {
        return retryTimeSeconds;
    }
}

2. 将106响应转为错误信号

在响应处理逻辑中,识别106响应并抛出上述自定义异常——因为retryWhen仅对错误信号触发重试,所以需要把正常返回的106响应转为错误信号:

Mono.fromCallable(() -> sendRequestToServer(params))
    .doOnSuccess(result -> {
        // 请根据实际响应格式实现这两个方法
        if (is106Response(result)) {
            long retryTime = parseRetryTimeFromResponse(result);
            throw new ServerRetryException(retryTime);
        }
        // 正常响应的处理逻辑
        handleResponse(result, grantMapEntry, deviceInfo);
    })

3. 替换为自定义重试策略

放弃原来的RetryBackoffSpec.backoff(),改用Retry.custom()构建支持动态退避的重试策略,在backoff逻辑中读取异常里的retryTime:

.retryWhen(Retry.custom()
    // 保留原有最大重试次数
    .maxAttempts(5)
    // 自定义退避时长:优先用服务器指定的retryTime,否则用默认10秒
    .backoff(ctx -> {
        Throwable ex = ctx.exception();
        if (ex instanceof ServerRetryException) {
            return Duration.ofSeconds(((ServerRetryException) ex).getRetryTimeSeconds());
        }
        return Duration.ofSeconds(10);
    })
    // 保留原有抖动配置
    .jitter(0.5)
    // 保留原有重试调度器
    .scheduler(hbRetryScheduler)
    // 优化重试日志,显示服务器指定的时长
    .doAfterRetry(ctx -> {
        Throwable ex = ctx.exception();
        String logMsg = ex instanceof ServerRetryException
                ? String.format("retrying after server-specified %ds", ((ServerRetryException) ex).getRetryTimeSeconds())
                : "retrying";
        log.warn(logMsg);
    })
    // 可选:只对特定异常触发重试,避免无关错误重试
    .filter(ctx -> ctx.exception() instanceof ServerRetryException || isRequestFailureException(ctx.exception()))
)
.subscribe();

关键逻辑说明

  • 异常传递:通过自定义异常把服务器返回的retryTime传递给重试策略,是实现动态退避的核心。
  • 动态退避:backoff()方法接收RetryContext,从中取出触发重试的异常,判断类型后选择对应的退避时长。
  • 兼容原有配置:保留了原有的重试次数、抖动、调度器、日志逻辑,仅修改退避时长的计算方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 10:28:40