当前位置: 首页 > 知识库问答 >
问题:

Spring Web Flux-WebClient-Exchange-block-如何释放到连接池的连接?

景志
2023-03-14

我使用的是spring-webflux-5.2.8。释放,此操作“正常”:

httpStatus = webClient
    .post()
    .uri(someUri)
    .headers(someHeaders)
    .bodyValue(someBody)
    .exchange()
    .map(ClientResponse::statusCode)
    .timeout(someTimeout)
    .doOnError(doSomething())
    .onErrorResume(ex -> Mono.empty())
    .block();

返回错误时,不会出现任何问题,因为连接已被破坏,并且不会放回连接池:

调试r.n.resources。PooledConnectionProvider-[id:0xa23f78ad,L:/127.0.0.1:7524!R:localhost/127.0.0.1:8443]通道已关闭,现在有0个活动连接和0个非活动连接

但当我得到成功响应时,下一篇帖子将失败/超时:

Java语言util。同时发生的TimeoutException:“map”中10000ms内未观察到任何项目或终端信号(且未配置回退)

由于需要进行故障排除,我使用了一个只有1个连接的修复连接池,如下所示:

@Bean
public WebClient.Builder webClientBuilder(){
    
    HttpClient httpClient = HttpClient.create(ConnectionProvider.create("pool", 1));
    
    return WebClient.builder()
        .clientConnector(new ReactorClientHttpConnector(httpClient));
}

我猜测(我可能错了,因为我对webclient和反应式世界完全陌生),问题是它在成功获得响应后没有释放连接,我认为这就是原因。

通过WebClient exchange()方法使用ClientResponse时,必须确保正文已被使用或释放。。。

我试着这样做一个releaseBody()(但由于下一篇文章仍然失败,所以这不起作用):

.map(clientResponse -> { 
    HttpStatus statusCode = clientResponse.statusCode();
    clientResponse.releaseBody();
    return statusCode;
})

附言:我需要使用block()。这不能更改,因为我需要响应才能继续前进,我只需要获取状态代码。我正在使用WebClient,因为我在某处读到Rest模板将被弃用以支持... WebClient。我希望有人能帮忙。

我启用了指标,但实际上连接没有释放:

reactor\u netty\u connection\u provider\u fixedPool\u total\u connections{id=“1591603494”,remote\u address=“localhost:8443”,}1.0 reactor\u netty\u connection\u provider\u fixedPool\u active\u connections{id=“1591603494”,remote\u address=“localhost:8443”,}1.0

找到此:<代码>https://github.com/spring-projects/spring-framework/issues/20474

我尝试了默认的连接数(即500个),我可以注意到,在每次发布后,活动连接数不断增加:-(

[reactor-超文本传输协议-nio-2]DEBUGr.n.resources.PooledConnectionProvider-[id: 0x2316e048, L:/127.0.0.1:32787-R:localhost/127.0.0.1: 8443]通道连接,现在有7个活动连接和0个非活动连接

共有1个答案

公良扬
2023-03-14

这就是我的工作:

HttpStatus httpStatus = null;
Mono<HttpStatus> monoHttpStatus  = null;
:           
WebClient webClient = xxx.getWebClient();
:       
try {
    monoHttpStatus  = webClient
        .post()
        .uri(someUri)
        .headers(someHeaders)
        .bodyValue(someBody)
        .exchange()
        .map(clientResponse -> 
            clientResponse.releaseBody().thenReturn(clientResponse.statusCode()))
        .timeout(someTimeout)
        .doOnError(Exception.class, e -> logger.error("An exception has occurred: ", e))
        .onErrorResume(ex -> Mono.empty())
        .block();
                
        if(monoHttpStatus != null)
            httpStatus = monoHttpStatus.block();            
}
:

//SomeOtherClass
@Autowired
private WebClient.Builder webClientBuilder;
public WebClient getWebClient() {
        
    :
    
    webClient= webClientBuilder.baseUrl(baseUrl)
                   .build();
    :   
    return webClient;
}

而我现在看到这个帖子写完之后:

调试Reactor。util。伐木工人$Slf4JLogger。调试[249][reactor-http-nio-1][id:0x6b0568a3,L:/127.0.0.1:10168-R:localhost/127.0.0.1:8443]释放通道
调试reactor。util。伐木工人$Slf4JLogger。调试[254][reactor-http-nio-1][id:0x6b0568a3,L:/127.0.0.1:10168-R:localhost/127.0.0.1:8443]通道已清理,现在0个活动连接和1个非活动连接

 类似资料:
  • 当我使用带有固定连接提供者的TCP客户端时,我不能重用连接。 他们使连接超过maxConnection变量。 这是我写的。 即使我使用10个maxConnection,比如“ConnectionProvider”。固定(“测试”,10)”,有22个空闲连接。天啊 //NettyClient.java //NettyClientTest。Java语言 14:55:27.397[reactor-tcp

  • 我已经按照这里的示例中所述配置了TcpClient。我试图使以下代码在服务器意外关闭连接的情况下具有弹性: 在这种情况下,我希望方法“getConnectionFromPool”能够从池中检索连接,或者如果没有可用的连接,则打开一个新连接。 注意到后。connect()最终服从于ConnectionProvider。acquire(),我尝试使用tcpClient。connect(),但有必要更改

  • Tomcat在使用后不释放连接的原因可能是什么? 这是我的配置

  • 问题内容: 我遍历了一堆URL,对于每个URL,我都在执行以下操作: 第一个查询很好,第二个查询抛出此异常: 线程“主”中的异常java.lang.IllegalStateException:无效使用SingleClientConnManager:仍然分配了连接。在分配另一个之前,请确保释放连接。在org.apache.http.impl.conn.SingleClientConnManager。

  • 这是释放回池的连接的正确方法吗 只是想确保这是正确的,因为如果我不调用连接,我的连接不会被重新循环

  • 使用来自DBCP的BasicDataSource,如果我们执行getConnection()并且在最后一个块中我们关闭连接,它是真的将连接返回到池还是关闭连接。我正在检查的代码片段是这样的 我正在检查BasicDataSource的源代码,并访问了这个包装类以获取连接。 委托对象的类型为java。sql。联系包装器代码调用委托的close方法,该方法将关闭集合,而不是将连接返回到池。这是DBCP的