Apache HTTP 客户端 - Apache Http 客户端中 0 个租用连接的问题

Posted

技术标签:

【中文标题】Apache HTTP 客户端 - Apache Http 客户端中 0 个租用连接的问题【英文标题】:Apache HTTP Client - Issues with 0 leased connections in Apache Http client 【发布时间】:2020-07-07 07:16:11 【问题描述】:

我正在尝试在我们的模块中使用 PoolingHttpClientConnectionManager。

下面是我的代码sn-p

import java.io.IOException;
import org.apache.hc.client5.http.ClientProtocolException;
import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.io.entity.EntityUtils;

public class Testme 
    static PoolingHttpClientConnectionManager connectionManager;
    static CloseableHttpClient httpClient;

    public static void main(String args[]) 
        connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setDefaultMaxPerRoute(3);
        connectionManager.setMaxPerRoute(new HttpRoute(new HttpHost("http://127.0.0.1",8887)), 5);
        httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager).build();
        System.out.println("Available connections "+connectionManager.getTotalStats().getAvailable());
        System.out.println("Max Connections "+connectionManager.getTotalStats().getMax());
        System.out.println("Number of routes "+connectionManager.getRoutes().size());
        Testme testme = new Testme();
        Testme.ThreadMe threads[] = new Testme.ThreadMe[5];
        for(int i=0;i<5;i++) 
            threads[i] = testme.new ThreadMe();

        for(Testme.ThreadMe thread:threads)  
            System.out.println("Leased connections before assigning "+connectionManager.getTotalStats().getLeased());
            thread.start(); 
        
    

    class ThreadMe extends Thread

        @Override
        public void run() 
            try 
                CloseableHttpResponse response= httpClient.execute(new HttpGet("http://127.0.0.1:8887"));
                System.out.println("Req for "+Thread.currentThread().getName() + " executed with "+response);
                try 
                    HttpEntity entity = response.getEntity();
                    EntityUtils.consume(entity);
                catch(IOException e) 
                    e.printStackTrace();    
                
                finally    
                    response.close();
                 
             catch (IOException e) 
                e.printStackTrace();
            
        
    

我收到的输出如下:

Available connections 0
Max Connections 25
Number of routes 0
Leased connections before assigning 0
Leased connections before assigning 0
Leased connections before assigning 0
Leased connections before assigning 0
Leased connections before assigning 0
Req for Thread-2 executed with 200 OK HTTP/1.1
Req for Thread-4 executed with 200 OK HTTP/1.1
Req for Thread-3 executed with 200 OK HTTP/1.1
Req for Thread-0 executed with 200 OK HTTP/1.1
Req for Thread-1 executed with 200 OK HTTP/1.1

尽管有请求正在执行,但我无法找到我的租用连接始终为 0。此外,尽管我已经注册了路线,但路线始终显示为 0。在我看来,有一些问题,但我无法识别它。执行期间可用的连接也显示为 0(尽管此处未打印)。请帮助我找出问题所在。谢谢!

【问题讨论】:

【参考方案1】:

"Available connections" 消息的第一个打印当然是 0,因为只有在您收到响应之后才会根据默认策略决定它DefaultClientConnectionReuseStrategy & DefaultConnectionKeepAliveStrategy,如果连接应该是可重用的,以及多长时间,只有这样连接才会被移动到可用连接列表

我猜路由的数量也是在至少创建一个连接之后决定的。

在您的日志中,您可以看到主线程打印了所有“在分配之前租用的连接” 消息子线程运行之前,因此您看到 0 个租用连接. 租用的连接列表中只有从创建到释放的连接,通常发生在response.readEntity()response.close() ,连接管理器的关闭,也可能在 EntityUtils.consume() 上。

所以也许尝试将“在分配之前租用的连接”从主线程移动到子线程。

【讨论】:

以上是关于Apache HTTP 客户端 - Apache Http 客户端中 0 个租用连接的问题的主要内容,如果未能解决你的问题,请参考以下文章

Apache HTTP 客户端 loadTrustMaterial 不起作用

更新后的 Apache 错误:客户端发送的 HTTP/1.1 请求没有主机名

apache http客户端中的异常

apache commons http客户端效率

Apache HTTP 客户端 socks 代理

Android 1.6 中捆绑了哪个版本的 Apache HTTP 客户端?