Spring boot Springboot Webclient引发readtimeout错误

Spring boot Springboot Webclient引发readtimeout错误,spring-boot,spring-webflux,Spring Boot,Spring Webflux,SpringWebClient抛出大量读取超时(每秒加载1000个请求)。我使用的是Springboot版本2.1.1.0。请查找下面的代码,如果我缺少任何配置,请告诉我: @Bean public WebClient webClient() { return WebClient.builder().build(); } public Mono<String> post(String url, JSONObject body) { Mono<String&g

SpringWebClient抛出大量读取超时(每秒加载1000个请求)。我使用的是Springboot版本2.1.1.0。请查找下面的代码,如果我缺少任何配置,请告诉我:

@Bean
public WebClient webClient() {
    return WebClient.builder().build();
}

public Mono<String> post(String url, JSONObject body) {

    Mono<String> result = webClient.post().uri(url)
            .contentType(MediaType.APPLICATION_JSON)
            .accept(MediaType.APPLICATION_JSON_UTF8)
            .body(BodyInserters.fromObject(body))
            .exchange()
            .flatMap { clientResponse ->
        return handleResponse(clientResponse)
    }
    return result;
}

private Mono<String> handleResponse(ClientResponse clientResponse) {
         if (clientResponse.statusCode().is4xxClientError() || clientResponse.statusCode().is5xxServerError()) {
            return clientResponse.bodyToMono(String.class)
                    .flatMap { errorBody ->
                return Mono.error(new CustomException(errorBody, clientResponse.statusCode().value()))
            }
        } else {
            return clientResponse.bodyToMono(String.class);
        }
    }
@Bean
公共网络客户端网络客户端(){
返回WebClient.builder().build();
}
公共Mono帖子(字符串url,JSONObject主体){
Mono result=webClient.post().uri(url)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION\u JSON\u UTF8)
.body(BodyInserters.fromObject(body))
.exchange()
.flatMap{clientResponse->
返回句柄响应(clientResponse)
}
返回结果;
}
专用单声道处理器响应(ClientResponse ClientResponse){
如果(clientResponse.statusCode().is4xxClientError()| | clientResponse.statusCode().is5xxServerError()){
return clientResponse.bodyToMono(String.class)
.flatMap{errorBody->
返回Mono.error(新的CustomException(errorBody,clientResponse.statusCode().value())
}
}否则{
返回clientResponse.bodytomino(String.class);
}
}
如前所述(谢谢!),这似乎不是框架中的错误

混淆源于这样一个事实:当同时运行多个web客户端请求并在反应管道上添加
log
操作符以获取更多信息时,日志会让您认为即使请求刚刚发出,读取超时也会被触发

如果我没记错的话,您在reactor.Mono.SwitchIfEmpty.48759等日志中看到的后缀号与订阅者绑定

对你来说,这意味着

13:55:50.287 [reactor-http-nio-6] INFO reactor.Mono.MapFuseable.49127 - | request(unbounded) 

与HTTP请求不同。Reactor在工作线程上调度任务,所以当您看到在同一线程上按顺序发生的事情时,并不意味着这些工作单元是为同一订阅服务器完成的

如果跟踪日志中的订户id,您应该会看到请求数据和不获取数据之间的时间大约为5秒

不是在最后一点上,我创建了一个Reactor HTTP服务器,它在10秒后发送响应体:

HttpServer.create().host("localhost").port(8080).handle((req, res) -> {
    return res.sendString(Flux.just("Hello")
        .delayElements(Duration.ofSeconds(10)), StandardCharsets.UTF_8);
}).bindNow().onDispose().block();
以及获取此数据的WebClient:

String response = WebClient.create().get().uri("http://localhost:8080/")
    .retrieve().bodyToMono(String.class).log().block();
System.out.println(response);

我没有收到任何读取超时。因此,应用程序中的某些内容必须配置这样的超时。

您能提供更多信息吗?您是否为客户端配置了超时?你能和我分享一下这个错误吗?使用JMeter请求远程服务时,您得到的最大延迟是什么?@BrianClozel
@Bean public WebClient WebClient(){TcpClient TcpClient=TcpClient.create().option(ChannelOption.CONNECT\u TIMEOUT\u milis,30000)。doOnConnected{connection->connection.addHandlerLast(新的ReadTimeoutHandler(5)).addHandlerLast(新的WriteTimeoutHandler(30))}ReactorClientHttpConnector=new ReactorClientHttpConnector(HttpClient.from(tcpClient));返回WebClient.builder().clientConnector(httpConnector).build();}
@BrianClozel我尝试了上述超时配置以及默认的
WebClient.builder().build();
。在这两种情况下,我都得到了readtimeout例外,您可以添加«log()»交换后的操作员并在此报告日志?@BrianClozel
池连接观察到错误2018-12-17T18:13:36.903185649Z io.netty.handler.timeout.ReadTimeoutException:null
这是我得到的错误日志。
String response = WebClient.create().get().uri("http://localhost:8080/")
    .retrieve().bodyToMono(String.class).log().block();
System.out.println(response);