为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

紫衣仙女 2022-06-23 20:05:43
Spring docs说需要手动为WebClient配置http客户端来设置超时:https ://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-client-builder -反应器超时。但是由于 WebClient 返回响应式 Mono,因此可以(api-wise)应用.timeout方法。它有同样的效果吗?此外,当一个人使用方法时,预计会使用.timeoutReactor 。TimeoutException如果手动完成配置,流中是否会出现相同的错误,即会doOnError(TimeoutException.class, ...)起作用吗?
查看完整描述

1 回答

?
慕斯王

TA贡献1864条经验 获得超2个赞

我的发现


以特定于 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 客户端特定配置来确保使用连接的本机和正确方式,同时添加新的处理程序,将与 http 客户端相关的异常包装成更通用的异常(或java.util.concurrent.TimeoutException),以便WebClient客户端不会依赖于提供程序异常。


查看完整回答
反对 回复 2022-06-23
  • 1 回答
  • 0 关注
  • 498 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号