提问人:pwflamy 提问时间:10/24/2023 更新时间:10/24/2023 访问量:43
Spring WebClient 内部如何工作以及 ReadTimeoutException 的原因
How Spring WebClient work inside and reason of ReadTimeoutException
问:
我有一个Spring WebClient,它通过以下方法构建:
public static WebClient build(ReactorResourceFactory factory) {
final ConnectionProvider fixedPool = ConnectionProvider
.builder("CustomClient")
.maxConnections(1000)
.pendingAcquireMaxCount(-1) // keep the backwards compatibility
.pendingAcquireTimeout(Duration.ofMillis(1000))
.maxIdleTime(Duration.ofSeconds(5))
.maxLifeTime(Duration.ofHours(1))
.build();
final LoopResources loop = LoopResources.create("CustomClient", 1, 4, true);
factory.setUseGlobalResources(false);
factory.setConnectionProvider(fixedPool);
factory.setLoopResources(loop);
Function<? super TcpClient, ? extends TcpClient> finalMapper = tcp -> tcp
.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler(500, TimeUnit.MILLISECONDS))
.addHandlerLast(new WriteTimeoutHandler(500, TimeUnit.MILLISECONDS)
))
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1500));
Function<HttpClient, HttpClient> mapper = c -> c.tcpConfiguration(finalMapper)
.compress(true)
.keepAlive(true)
.disableRetry(true);
ClientHttpConnector connector = new ReactorClientHttpConnector(factory, mapper);
return WebClient.builder().clientConnector(connector).build();
}
有时,即使另一方发送了成功的响应,此客户端也会生成 ReadTimeoutException。当 serviceA 同时进行大量调用(10-50 毫秒内有 30-50 个请求)时,最常发生这种情况。因此,在日志中,我观察到以下情况(ServiceA 向 ServiceB 发出请求):
服务A
Oct 24, 2023 @ 12:16:08.946 INFO request in 0.585 secs
Oct 24, 2023 @ 12:16:08.939 [CustomClient-epoll-3] WARN reactor.netty.http.client.HttpClientConnect || >> [0eac89ee-1, L:/<ip>:56790 - R:<host>/<ip>:443] The connection observed an error
Oct 24, 2023 @ 12:16:08.939 io.netty.handler.timeout.ReadTimeoutException: null
服务B
Oct 24, 2023 @ 12:16:08.568 INFO Last successful response to ServiceA
据我了解,ServiceB 成功处理了所有请求,但 ServiceA 中的 WebClient 由于某种原因没有处理响应并抛出 ReadTimeoutException。
问题:
- Spring WebClient 是如何在后台工作的?当我们调用时会发生什么情况,ReadTimeoutException 的倒计时在什么时间点开始?
retrive()
- 如何解决这个问题?超时是由于 LoopResources 中缺少线程还是什么原因而引发的?
答: 暂无答案
评论