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

Spring WebFlux:未超时却触发Timeout Handler问题排查与解决

问题原因分析

你遇到的这个问题其实是个常见的Java方法调用陷阱——handler()方法在构建Mono链的时候就被立即执行了,而不是等到超时事件触发时才调用。

看你的代码:

.timeout(Duration.ofSeconds(100), handler())

这里的第二个参数要求是一个Mono<? extends Integer>,所以Java在执行这条语句时,会先计算handler()的返回值,也就是立刻调用handler(),打印出"handler invoked",然后把返回的Mono.just(10)传给timeout方法。

而实际的超时逻辑是:原Mono在1秒后就正常发射了元素,timeout判断没有超时,所以并不会切换到这个提前准备好的fallback Mono,最终订阅的还是原Mono的1,所以你会看到先打印handler invoked,再打印1。

实现预期行为的解决方案

要让handler()只在真正发生超时的时候才被调用,你需要使用timeout的另一个重载方法,它接受一个Supplier<Mono<? extends Integer>>(延迟提供fallback的接口),这样只有超时发生时,才会调用Supplier的get()方法来生成fallback Mono。

修改后的代码如下:

public static void main(String[] args) throws InterruptedException {
    Mono<Integer> integerMono = Mono.just(1).delayElement(Duration.ofSeconds(1));
    integerMono
        // 改用Supplier,延迟调用handler()
        .timeout(Duration.ofSeconds(100), () -> handler())
        .subscribe(integer -> System.out.println(integer));
    Thread.sleep(10000);
}

private static Mono<? extends Integer> handler() {
    System.out.println("handler invoked");
    return Mono.just(10);
}

验证效果

修改后,原Mono在1秒后正常发射元素,不会触发超时逻辑,所以handler()不会被调用,输出只会是1。如果把原Mono的延迟改成101秒(超过100秒的超时时间),这时候才会触发handler(),输出handler invoked和10。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:17:37