gpt4 book ai didi

java - 如何在Spring WebClient中设置和处理超时?

转载 作者:行者123 更新时间:2023-11-30 01:55:17 25 4
gpt4 key购买 nike

Spring 文档说需要手动为 WebClient 配置 http 客户端来设置超时:https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-client-builder-reactor-timeout 。但由于 WebClient 返回响应式 Mono,因此可以(api-wise)应用 .timeout 方法。

有同样的效果吗?

此外,当使用.timeout方法时,Reactor的TimeoutException是预料之中的。如果手动完成配置,流中是否会出现相同的错误,即 doOnError(TimeoutException.class, ...) 有效吗?

最佳答案

我的发现

以 http 客户端特定方式设置超时将导致 http 客户端特定异常,即 WebClient 不包装异常:

@Test
void test() {
var host = "localhost";
var endpoint = "/test";
var port = 8089;
var timeout = Duration.ofSeconds(3);

WireMockServer wireMockServer = new WireMockServer(wireMockConfig().port(8089));
wireMockServer.start();
WireMock.configureFor(host, wireMockServer.port());

WireMock.stubFor(get(urlEqualTo(endpoint))
.willReturn(aResponse().withFixedDelay((int) timeout.toMillis())));

HttpClient httpClient = HttpClient.create()
.tcpConfiguration(client ->
client.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler((int) (timeout.toSeconds() / 2)))
.addHandlerLast(new WriteTimeoutHandler((int) (timeout.toSeconds() / 2)))));

WebClient webClient = WebClient.builder()
.baseUrl(format("http://%s:%d", host, port))
.clientConnector(new ReactorClientHttpConnector(httpClient)).build();

webClient.get().uri(endpoint).retrieve().bodyToMono(Recommendation.class).block();
}

这将导致io.netty.handler.timeout.ReadTimeoutException

.timeout(timeout.dividedBy(2)).block() 会导致常规的 TimeoutException (java.util.concurrent),但是Web 客户端是否关心之后的连接(可能不会)仍然是一个悬而未决的问题。

我的解决方案是使用http客户端特定的配置来确保使用连接的 native 和正确的方式,同时添加新的处理程序,将http客户端相关的异常包装成更通用的异常(或java.util.concurrent.TimeoutException) >) 以便 WebClient 客户端不会依赖于提供程序异常。

关于java - 如何在Spring WebClient中设置和处理超时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54733116/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com