복붙노트

[SPRING] Spring WebFlux 웹 클라이언트에서 시간 제한 설정

SPRING

Spring WebFlux 웹 클라이언트에서 시간 제한 설정

Spring Webflux WebClient를 사용하여 스프링 부트 애플리케이션에서 REST 호출을 작성한다. 그리고 매 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().<b><i>timeout(Duration.ofMillis(600000))</i></b>
            .flatMap(response -> handleResponse(response, name, offset));

위 옵션 중 어느 것도 나를 위해 일하지 않습니다.

org.springframework.boot를 사용하고 있습니다 : spring-boot-gradle-plugin : 내부적으로 org.springframework의 의존성이있는 2.0.0.M7 : spring-webflux : 5.0.2.RELEASE.

여기서 제안을하고 내가 잘못하고 있다면 알려주세요.

해결법

  1. ==============================

    1.문제를 재현하려고 시도했지만 시도하지 못했습니다. reactor-netty를 사용하여 0.7.5.RELEASE.

    문제를 재현하려고 시도했지만 시도하지 못했습니다. 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
    
  2. from https://stackoverflow.com/questions/48992992/set-timeout-in-spring-webflux-webclient by cc-by-sa and MIT license