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

如何在Project Reactor中获取下次重试前的退避时长?

在Project Reactor 3.6+中获取重试退避时长的方法

问题描述

此前使用已废弃的reactor.retry.Retry类时,可通过ctx.backoff().seconds获取下次重试的退避时长:

var myFlux = Flux.of(...)
myFlux.retry(Retry
            .anyOf(TimeoutException.class)
            .exponentialBackoff(Duration.ofSeconds(1), Duration.ofSeconds(5)).retryMax(5)
            .doOnRetry(ctx -> {
                var e = (TimeoutException) ctx.exception();
                var secondsToWaitBeforeNextRetry = ctx.backoff().seconds;
                log.info("Will retry again in roughly {} s", secondsToWaitBeforeNextRetry);
            })
)

但官方建议改用reactor.util.retry.RetryBackoffSpec后,找不到等价的获取方式,现有转换后的代码中需要补充获取退避时长的逻辑:

var myFlux = Flux.of(...)
myFlux.retryWhen(RetryBackoffSpec.backoff(5, Duration.ofSeconds(1)).maxBackoff(Duration.ofSeconds(5))
                .filter(TimeoutException.class::isAssignableFrom)
                .doBeforeRetry(signal -> {
                    var e = (TimeoutException) signal.exception();
                    var secondsToWaitBeforeNextRetry = // TODO What to write here?
                    log.info("Will retry again in roughly {} s", secondsToWaitBeforeNextRetry);
                })
)

解决方案

可以通过RetrySignal获取RetryContextView,再调用其backoff()方法拿到退避时长,具体代码修改如下:

var myFlux = Flux.of(...)
myFlux.retryWhen(RetryBackoffSpec.backoff(5, Duration.ofSeconds(1))
                .maxBackoff(Duration.ofSeconds(5))
                .filter(TimeoutException.class::isAssignableFrom)
                .doBeforeRetry(signal -> {
                    var e = (TimeoutException) signal.exception();
                    // 获取退避时长并转换为秒
                    var backoffDuration = signal.context().backoff();
                    var secondsToWaitBeforeNextRetry = backoffDuration.getSeconds();
                    log.info("Will retry again in roughly {} s", secondsToWaitBeforeNextRetry);
                })
)
  • signal.context()返回RetryContextView,这是新API中承载重试上下文信息的类
  • RetryContextView.backoff()直接返回本次重试的退避Duration,可以通过getSeconds()、toMillis()等方法转换为需要的时间单位

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:12:18