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

JDK 11环境下WebClient调用抛出TimeoutException问题求助

JDK 11环境下WebClient调用TimeoutException问题排查与解决

在JDK 11(zulu-jdk11.0.14)环境中使用WebClient调用接口时,出现如下TimeoutException:

Caused by: java.util.concurrent.TimeoutException: Did not observe any item or terminal signal within 60000ms in 'source(MonoDefer)' (and no fallback has been configured)
        at reactor.core.publisher.FluxTimeout$TimeoutMainSubscriber.handleTimeout(FluxTimeout.java:295) ~[reactor-core-3.4.24.jar!/:3.4.24]

但在JDK 8(zulu8.61.0.18-sa-jdk8.0.331)环境下运行同一测试用例则完全正常,无异常出现。

应用基于Spring Boot 2.7.5构建,依赖spring-boot-starter-webflux,其中reactor-netty-http版本为1.0.24:

<dependency>
    <groupId>io.projectreactor.netty</groupId>
    <artifactId>reactor-netty-http</artifactId>
    <version>1.0.24</version>
</dependency>

观察到的现象

  • 现象1:闲置连接异常关闭后,重新调用正常
    WebClient调用后闲置约30秒,连接会伴随SslCloseCompletionEvent(java.nio.channels.ClosedChannelException)关闭并注销:
2022-11-14 11:17:47.773 DEBUG 7600 --- [ctor-http-nio-3] reactor.netty.http.client.HttpClient     : [3d257d24, L:/xx.xx.xx.xx:64172 - R:nnctj2prxc4t.apps.internal.xxxx.net/xx.xx.xx.xx:443] READ COMPLETE
2022-11-14 11:18:17.264 DEBUG 7600 --- [ctor-http-nio-3] reactor.netty.http.client.HttpClient     : [3d257d24, L:/xx.xx.xx.xx:64172 - R:nnctj2prxc4t.apps.internal.xxxx.net/xx.xx.xx.xx:443] READ COMPLETE
2022-11-14 11:18:17.265 DEBUG 7600 --- [ctor-http-nio-3] reactor.netty.http.client.HttpClient     : [3d257d24, L:/xx.xx.xx.xx:64172 ! R:nnctj2prxc4t.apps.internal.xxxx.net/xx.xx.xx.xx:443] USER_EVENT: SslCloseCompletionEvent(java.nio.channels.ClosedChannelException)
2022-11-14 11:18:17.265 DEBUG 7600 --- [ctor-http-nio-3] reactor.netty.http.client.HttpClient     : [3d257d24, L:/xx.xx.xx.xx:64172 ! R:nnctj2prxc4t.apps.internal.xxxx.net/xx.xx.xx.xx:443] INACTIVE
2022-11-14 11:18:17.265 DEBUG 7600 --- [ctor-http-nio-3] reactor.netty.http.client.HttpClient     : [3d257d24, L:/xx.xx.xx.xx:64172 ! R:nnctj2prxc4t.apps.internal.xxxx.net/xx.xx.xx.xx:443] UNREGISTERED

此时再次发送请求,会注册新连接并调用成功:

2022-11-14 11:18:59.542 DEBUG 7600 --- [ctor-http-nio-4] reactor.netty.http.client.HttpClient     : [476de49d] REGISTERED
2022-11-14 11:18:59.630 DEBUG 7600 --- [ctor-http-nio-4] reactor.netty.http.client.HttpClient     : [476de49d] CONNECT: nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443
2022-11-14 11:18:59.743 DEBUG 7600 --- [ctor-http-nio-4] reactor.netty.http.client.HttpClient     : [476de49d, L:/xx.xx.xx.xx:64197 - R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] ACTIVE
2022-11-14 11:18:59.849 DEBUG 7600 --- [ctor-http-nio-4] reactor.netty.http.client.HttpClient     : [476de49d, L:/xx.xx.xx.xx:64197 - R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] READ COMPLETE
2022-11-14 11:18:59.858 DEBUG 7600 --- [ctor-http-nio-4] reactor.netty.http.client.HttpClient     : [476de49d, L:/xx.xx.xx.xx:64197 - R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] USER_EVENT: SslHandshakeCompletionEvent(SUCCESS)
2022-11-14 11:18:59.860 DEBUG 7600 --- [ctor-http-nio-4] reactor.netty.http.client.HttpClient     : [476de49d-1, L:/xx.xx.xx.xx:64197 - R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] WRITE: 2023B 
  • 现象2:连接正常关闭后,重新调用触发超时
    若连接伴随SslCloseCompletionEvent(SUCCESS)正常关闭并注销:
2022-11-14 09:10:41.295 DEBUG 21332 --- [ctor-http-nio-4] reactor.netty.http.client.HttpClient     : [9a6b8e52, L:/xx.xx.xx.xx:56897 - R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] CLOSE
2022-11-14 09:10:41.303 DEBUG 21332 --- [ctor-http-nio-4] reactor.netty.http.client.HttpClient     : [9a6b8e52, L:/xx.xx.xx.xx:56897 ! R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] USER_EVENT: SslCloseCompletionEvent(SUCCESS)
2022-11-14 09:10:41.303 DEBUG 21332 --- [ctor-http-nio-4] reactor.netty.http.client.HttpClient     : [9a6b8e52, L:/xx.xx.xx.xx:56897 ! R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] READ COMPLETE
2022-11-14 09:10:41.303 DEBUG 21332 --- [ctor-http-nio-4] reactor.netty.http.client.HttpClient     : [9a6b8e52, L:/xx.xx.xx.xx:56897 ! R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] INACTIVE
2022-11-14 09:10:41.303 DEBUG 21332 --- [ctor-http-nio-4] reactor.netty.http.client.HttpClient     : [9a6b8e52, L:/xx.xx.xx.xx:56897 ! R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] UNREGISTERED

此时再次发送请求,虽注册新连接但仍触发TimeoutException:

2022-11-14 09:11:32.362 DEBUG 21332 --- [ctor-http-nio-5] reactor.netty.http.client.HttpClient     : [ad2bc21d] REGISTERED
2022-11-14 09:11:32.424 DEBUG 21332 --- [ctor-http-nio-5] reactor.netty.http.client.HttpClient     : [ad2bc21d] CONNECT: nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443
2022-11-14 09:11:32.528 DEBUG 21332 --- [ctor-http-nio-5] reactor.netty.http.client.HttpClient     : [ad2bc21d, L:/xx.xx.xx.xx:56922 - R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] ACTIVE
2022-11-14 09:11:32.970 DEBUG 21332 --- [ctor-http-nio-5] reactor.netty.http.client.HttpClient     : [ad2bc21d, L:/xx.xx.xx.xx:56922 - R:nnctj2prxc4t.apps.internal.xxxxxx.net/xx.xx.xx.xx:443] READ COMPLETE
2022-11-14 09:11:33.063 DEBUG 21332 --- [ctor-http-nio-5] reactor.netty.http.client.HttpClient     : [ad2bc21d, L:/xx.xx.xx.xx:56922 - R:nnctj2prxc4t.apps.internal.xxxxxx.net/xx.xx.xx.xx:443] READ COMPLETE
2022-11-14 09:11:33.063 DEBUG 21332 --- [ctor-http-nio-5] reactor.netty.http.client.HttpClient     : [ad2bc21d, L:/xx.xx.xx.xx:56922 - R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] READ COMPLETE
2022-11-14 09:11:33.165 DEBUG 21332 --- [ctor-http-nio-5] reactor.netty.http.client.HttpClient     : [ad2bc21d, L:/xx.xx.xx.xx:56922 - R:nnctj2prxc4t.apps.internal.xxxxx.net/xx.xx.xx.xx:443] USER_EVENT: SslHandshakeCompletionEvent(SUCCESS)
...

Caused by: java.util.concurrent.TimeoutException: Did not observe any item or terminal signal within 60000ms in 'source(MonoDefer)' (and no fallback has been configured)
        at reactor.core.publisher.FluxTimeout$TimeoutMainSubscriber.handleTimeout(FluxTimeout.java:295) ~[reactor-core-3.4.24.jar!/:3.4.24]

解决建议

1. 升级Reactor Netty版本

Reactor Netty 1.0.24存在部分JDK 11兼容性问题,建议升级至1.0.26或更高版本(Spring Boot 2.7.x兼容范围内),新版本修复了JDK 11下的连接管理和SSL相关bug。

修改依赖配置:

<dependency>
    <groupId>io.projectreactor.netty</groupId>
    <artifactId>reactor-netty-http</artifactId>
    <version>1.0.26</version>
</dependency>

2. 调整WebClient连接池配置

显式配置连接池的最大空闲时间和生命周期,避免复用已失效的连接:

import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.PoolResources;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import java.time.Duration;

WebClient webClient = WebClient.builder()
        .clientConnector(new ReactorClientHttpConnector(
                HttpClient.create()
                        .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
                        .doOnConnected(conn -> conn
                                .addHandlerLast(new ReadTimeoutHandler(10))
                                .addHandlerLast(new WriteTimeoutHandler(10)))
                        .poolResources(PoolResources.fixed("webclient-pool", 10)
                                .maxIdleTime(Duration.ofSeconds(20))
                                .maxLifeTime(Duration.ofSeconds(60)))
        ))
        .build();

3. 添加请求重试机制

针对连接超时场景,添加重试策略,确保请求在连接失效时重新发起:

import reactor.util.retry.Retry;
import java.util.concurrent.TimeoutException;

webClient.get()
        .uri("/api/xxx")
        .retrieve()
        .bodyToMono(String.class)
        .retryWhen(Retry.fixedDelay(3, Duration.ofSeconds(1))
                .filter(throwable -> throwable instanceof TimeoutException))
        .block();

4. 调整JDK 11 SSL参数

JDK 11对SSL默认配置做了调整,可显式指定SSL provider或禁用某些特性:

import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import reactor.netty.http.client.HttpClient;

HttpClient httpClient = HttpClient.create()
        .secure(sslContextSpec -> sslContextSpec.sslContext(SslContextBuilder.forClient()
                .sslProvider(SslProvider.JDK)
                .build()));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:01:37