web-dev-qa-db-ja.com

Spring WebFlux Webクライアントでタイムアウトを設定する

私はSpring Webflux WebClientを使用してRESTをSpringブートアプリケーションから呼び出します。また、毎回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));
            }));

そして、「clientConnector」メソッドを使用して、この上記のコネクタ設定を「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:spring-webflux:5.0.2.RELEASEの依存関係を内部的に持っているorg.springframework.boot:spring-boot-gradle-plugin:2.0.0.M7を使用しています。

ここで提案して、私がここで何か悪いことをしているかどうか知らせてください。

9

問題を再現しようとしましたが、できませんでした。 reactor-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のReadTimeoutHandlerおよびWriteTimeoutHandlerを確認できます。

完全な例は次のようになります。

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());

Reactor 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
17
Brian Clozel