Spring WebFlux WebClient中MaxConnPerRoute等参数配置问题咨询
RestTemplate 迁移 WebClient 连接池配置问题解答
背景
我们已基于 RestTemplate 实现自定义连接池:
PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); poolingConnManager.setDefaultMaxPerRoute(restClientprops.getRestClientMaxPerRoutePool()); poolingConnManager.setMaxTotal(restClientprops.getRestClientMaxTotalPool()); HttpClientBuilder httpClientBuilder = HttpClients.custom() .setConnectionManager(poolingConnManager) .setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE) .setMaxConnPerRoute(restClientprops.getRestClientMaxPerRoutePool()) .setMaxConnTotal(restClientprops.getRestClientMaxTotalPool()); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setConnectTimeout(restClientprops.getConnectTimeout()); requestFactory.setReadTimeout(restClientprops.getReadTimeout()); requestFactory.setConnectionRequestTimeout(restClientprops.getConnectionRequestTimeout()); requestFactory.setHttpClient(httpClientBuilder.build()); this.restTemplate = new RestTemplate(requestFactory);
计划迁移至 WebClient,已编写部分代码:
HttpClient httpClient = HttpClient .create(ConnectionProvider.create("webclient-pool", restClientprops.getRestClientMaxTotalPool())) .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, restClientprops.getConnectTimeout()) .responseTimeout(Duration.ofMillis(restClientprops.getConnectionRequestTimeout())) .doOnConnected(conn -> conn.addHandler(new ReadTimeoutHandler(restClientprops.getReadTimeout(), TimeUnit.MILLISECONDS))) .keepAlive(true);
针对以下问题逐一解答:
1. RestTemplate 中的 ConnectionRequestTimeout 是否对应 WebClient 的 responseTimeout?
不等价。
- RestTemplate 的
ConnectionRequestTimeout:是从连接池获取空闲连接的等待超时时间,如果池内无可用连接且已达最大连接数,等待超过这个时间就会抛出超时异常。 - WebClient 的
responseTimeout:是整个请求从发送到接收完响应的总超时时间,涵盖连接建立、请求发送、响应接收的全流程。
正确对应 ConnectionRequestTimeout 的是 WebClient 连接池的 acquireTimeout,需在 ConnectionProvider 中配置:
ConnectionProvider connectionProvider = ConnectionProvider.builder("webclient-pool") .maxConnections(restClientprops.getRestClientMaxTotalPool()) .acquireTimeout(Duration.ofMillis(restClientprops.getConnectionRequestTimeout())) .build();
2. 如何在 WebClient 中配置 RestTemplate 里的 MaxConnPerRoute 参数?
RestTemplate 的 MaxConnPerRoute 是指单个路由(目标主机)允许的最大连接数,在 WebClient 中可通过 ConnectionProvider.Builder 的 maxConnectionsPerRoute 方法配置:
ConnectionProvider connectionProvider = ConnectionProvider.builder("webclient-pool") .maxConnections(restClientprops.getRestClientMaxTotalPool()) // 对应 RestTemplate 的 MaxTotal .maxConnectionsPerRoute(restClientprops.getRestClientMaxPerRoutePool()) // 对应 RestTemplate 的 MaxConnPerRoute .build(); HttpClient httpClient = HttpClient.create(connectionProvider) // 其他配置项...
3. keepAlive(true) 是否等价于 RestTemplate 中的 setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)?
不等价,两者作用机制完全不同:
DefaultConnectionKeepAliveStrategy.INSTANCE:遵循 HTTP 响应头中的Keep-Alive字段决定连接存活时间,是应用层(HTTP)的连接复用策略,会根据服务器返回的超时时间保持连接,超时后关闭。- WebClient 的
keepAlive(true):启用的是TCP 层的 keep-alive 机制,通过 TCP 心跳包检测连接是否存活,和 HTTP 协议的连接复用逻辑无关。
若要实现和 RestTemplate 默认存活策略等价的逻辑,需自定义处理 HTTP 响应的 Keep-Alive 头,可通过 doOnConnected 添加自定义 handler 或利用 Reactor Netty 的相关配置实现连接复用管理。
内容的提问来源于stack exchange,提问作者Gayatri
相关产品推荐
相关产品推荐

