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

高流量下Reactor Netty WebClient出现Timeout Exception问题求助

问题分析

你的问题核心不是下游服务的15秒响应时间,而是高并发下WebClient连接池资源不足,导致请求排队等待连接的时间+下游响应时间超过了20秒的总超时限制,从而触发TimeoutException。

具体细节:

  • 你设置的20秒超时是整个请求链路的总时长(包含获取连接、发送请求、等待响应的全部时间)
  • 默认Reactor Netty HttpClient的连接池配置(如最大连接数)无法支撑每秒20请求的并发量,大量请求需要排队等待空闲连接
  • 排队耗时(如5秒以上)加上下游15秒的响应时间,总和超过20秒,最终触发超时

另外代码中存在无意义操作:.flatMap(Mono::just),toEntity(String.class)已经返回Mono类型,这个flatMap步骤对结果没有任何作用,反而增加了不必要的订阅开销,可直接移除。

解决方案

1. 优化WebClient连接池配置

通过自定义Reactor Netty HttpClient配置连接池参数,确保并发请求能及时获取连接:

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient webClient() {
        HttpClient httpClient = HttpClient.create()
                // 配置连接池核心参数
                .poolConfiguration(pool -> pool
                        // 根据并发量调整最大连接数,示例设为50
                        .maxConnections(50)
                        // 设置等待获取连接的超时时间,避免无限排队
                        .pendingAcquireTimeout(Duration.ofSeconds(5))
                        // 设置连接空闲超时时间,回收闲置连接
                        .maxIdleTime(Duration.ofSeconds(30))
                )
                // 单独配置连接超时与响应超时,实现更精细的控制
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
                .responseTimeout(Duration.ofSeconds(15));

        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .build();
    }
}

修改Test类,直接注入配置好的WebClient,避免每次build新实例:

@RestController
@RequiredArgsConstructor
public class Test {

  private final WebClient webClient;

  public Mono<?> call() {
    return webClient.method(HttpMethod.GET)
        .uri("http://localhost:8080/ms-test-webclient/delay")
        .headers(httpHeaders -> httpHeaders.set("Content-Type", "application/json"))
        .retrieve()
        .toEntity(String.class)
        .timeout(Duration.ofSeconds(20))
        .onErrorResume(TimeoutException.class, ex -> {
          String message = "Webclient timeout";
          return Mono.error(new TimeoutException(message).initCause(ex));
        });
  }

  // 其余方法保持不变...
}

2. 调整总超时时间

如果暂时无法修改连接池配置,可适当延长总超时时间,确保排队时间+下游响应时间不会超出限制:

.timeout(Duration.ofSeconds(25))

3. 移除无意义的flatMap操作

直接删除.flatMap(Mono::just)步骤,减少不必要的链路开销。

验证方案

调整配置后,用JMeter以每秒20请求的流量压测,观察是否仍有超时情况。若问题持续,可进一步调大maxConnections的值,或检查下游服务在高并发下是否出现响应延迟增加的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:44:54