在Spring WebFlux WebClient中设置超时



我正在使用Spring WebFlux WebClient从我的Spring Boot应用程序中进行休息调用。每次在30秒内获得超时。

这是我尝试在Spring Webfulx的Webclient中设置套接字超时的一些代码。

 - ReactorClientHttpConnector connector = new ReactorClientHttpConnector(options -> options
           .option(ChannelOption.SO_TIMEOUT, 600000).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 600000));
 - ReactorClientHttpConnector connector = new ReactorClientHttpConnector(
           options -> options.afterChannelInit(chan -> {
                chan.pipeline().addLast(new ReadTimeoutHandler(600000));
            }));
 - ReactorClientHttpConnector connector1 = new ReactorClientHttpConnector(options -> options
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 600000).afterNettyContextInit(ctx -> {
                ctx.addHandlerLast(new ReadTimeoutHandler(600000, TimeUnit.MILLISECONDS));
            }));

并尝试通过使用"客户端连接"方法在" WebClient"中添加以上连接器设置。

,还尝试将超时设置如下:

webClient.get().uri(builder -> builder.path("/result/{name}/sets")
                    .queryParam("q", "kind:RECORDS")
                    .queryParam("offset", offset)
                    .queryParam("limit", RECORD_COUNT_LIMIT)
                    .build(name))
            .header(HttpHeaders.AUTHORIZATION, accessToken)
            .exchange().timeout(Duration.ofMillis(600000))
            .flatMap(response -> handleResponse(response, name, offset));

上述选项都不适合我。

我正在使用org.springframework.boot:spring-boot-gradle-plugin:2.0.0.m7,在内部具有org.springframework:spring-webflux:5.0.2.release:5.0.2.release。

请在这里建议,让我知道我在这里是否做错了。

我尝试过重现问题,但不能。使用反应器netty 0.7.5.Release。

我不确定您在谈论哪个超时。

可以使用ChannelOption.CONNECT_TIMEOUT_MILLIS配置连接超时。我在"连接"日志消息和实际错误之间获得了10秒:

WebClient webClient = WebClient.builder()
    .clientConnector(new ReactorClientHttpConnector(options -> options
        .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)))
    .build();
webClient.get().uri("http://10.0.0.1/resource").exchange()
    .doOnSubscribe(subscription -> logger.info("connecting"))
    .then()
    .doOnError(err -> logger.severe(err.getMessage()))
    .block();

如果您要谈论的是阅读/写入超时,则可以查看Netty的ReadTimeoutHandlerWriteTimeoutHandler

一个完整的例子看起来像这样:

ReactorClientHttpConnector connector = new ReactorClientHttpConnector(options ->
        options.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10)
                .onChannelInit(channel -> {
                        channel.pipeline().addLast(new ReadTimeoutHandler(10))
                                .addLast(new WriteTimeoutHandler(10));
                return true;
        }).build());

从反应堆Netty 0.8和Spring Framework 5.1开始,该配置现在看起来像:

TcpClient tcpClient = TcpClient.create()
                 .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000)
                 .doOnConnected(connection ->
                         connection.addHandlerLast(new ReadTimeoutHandler(10))
                                   .addHandlerLast(new WriteTimeoutHandler(10)));
WebClient webClient = WebClient.builder()
    .clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient)))
    .build();

也许将以下内容添加到您的application.properties将提供有关HTTP级别发生的情况的更多信息:

logging.level.reactor.ipc.netty.channel.ContextHandler=debug
logging.level.reactor.ipc.netty.http.client.HttpClient=debug

,因为HttpClient.from(tcpClient)现在已在最新的Netty中弃用(v0.9.x,并将在v1.1.0中删除(。您可以使用responseTimeout(),而忽略太多的HTTP连接配置,您在其他代码中看到这些配置,并且此实现与旧代码以及新代码一起工作。

创建httpclient

HttpClient httpClient = HttpClient.create().responseTimeout(Duration.ofMillis(500)); // 500 -> timeout in millis

使用WebClient Builder FXN .clientConnector()

添加httpclient到WebClient
WebClient
.builder()
.baseUrl("http://myawesomeurl.com")
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();

此外,网站上可用的大多数实施不推荐,以确保您不使用不弃用的链接,您可以查看此链接。

fyi:对于较旧的Netty版本(即< v0.9.11版本(responseTimeout()在引擎盖下使用tcpconfiguration((,在新版本中被弃用。但是ResponsEtion Out((在> = v0.9.11中使用新实现,因此,即使您将来更改项目的Netty版本,您的代码也不会破坏。

注意:如果您使用的是默认情况下的旧Netty版本,有时还可以使用Brian的实现。(虽然不确定(

如果您想阅读有关ResponseTion out((的更多信息以及如何工作,则可以在此处和此处检查源代码或此处的GitHub Gist。

HttpClient.from(TcpClient)方法@IM_BHATMAN提到,已弃用,这是一种使用良好的方式。

// works for Spring Boot 2.4.0, 2.4.1, and 2.4.2
// doesn't work for Spring Boot 2.3.6, 2.3.7, and 2.3.8
HttpClient httpClient = HttpClient.create()
        //.responseTimeout(Duration.ofSeconds(READ_TIMEOUT_SECONDS))
        .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIME_MILLIS)
        .doOnConnected(c -> {
                c.addHandlerLast(new ReadTimeoutHandler(READ_TIMEOUT_SECONDS))
                 .addHandlerLast(new WriteTimeoutHandler(WRITE_TIMEOUT_SECONDS));
        });
ClientConnector clientConnector = new ReactorClientHttpConnector(httpClient);
WebClient webClient = WebClient.builder()
        .clientConnector(clientConnector)
        ...
        .build();

我不确定

的差异
  • HttpClient#responseTimeout(...)
  • HttpClient#doOnConnected(c -> c.addHandler(new ReadTimeoutHandler(...)))

请参阅下面的代码块,以使用WebClient

设置超时和重试
.retrieve()
            .onStatus(
                   (HttpStatus::isError), // or the code that you want
                    (it -> handleError(it.statusCode().getReasonPhrase())) //handling error request
           )
            .bodyToMono(String.class)
            .timeout(Duration.ofSeconds(5))
            .retryWhen(
                    Retry.backoff(retryCount, Duration.ofSeconds(5))
                            .filter(throwable -> throwable instanceof TimeoutException)
           )

相关内容

  • 没有找到相关文章

最新更新