为啥 PoolingHttpClientConnectionManager 提供越来越慢的连接?

Posted

技术标签:

【中文标题】为啥 PoolingHttpClientConnectionManager 提供越来越慢的连接?【英文标题】:Why is PoolingHttpClientConnectionManager providing increasingly slow connections?为什么 PoolingHttpClientConnectionManager 提供越来越慢的连接? 【发布时间】:2015-03-19 21:29:18 【问题描述】:

我正在使用 httpClient 4.3.6CloseableHttpClientPoolingHttpClientConnectionManager 提供服务。

我当前的设置包括 200 个线程同时通过客户端执行 GET 请求。我试图最大化线程每秒可以处理的请求数,但是一旦我开始执行超过 ~100/s,httpClient.execute() 请求就会开始花费越来越多的时间来返回。我知道服务请求的机器并没有变慢,问题的根源在于 httpClient 库或我机器上的资源。

这是我的客户端实例化

    // Start up an eviction thread.
    // remove idle (for 50ms) connections every 50 ms
    IdleConnectionMonitorThread monitor = new IdleConnectionMonitorThread(cm);
    // Don't stop quitting.
    monitor.setDaemon(true);
    monitor.start();

    PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
    // increase connection limit
    cm.setMaxTotal(2000);
    cm.setDefaultMaxPerRoute(2000);
    // create client
    HttpClientBuilder builder = HttpClientBuilder.create();
    builder.setDefaultRequestConfig(RequestConfig.custom().build());
    builder.setConnectionManager(cm);
    this.httpClient = builder.build();

execute 方法的平均执行时间在我开始执行线程时稳定但缓慢地增加,并在请求率下降时迅速下降。

    HttpGet getRequest = new HttpGet(uri);
    HttpClientContext context = HttpClientContext.create();

    try(CloseableHttpResponse response = httpClient.execute(getRequest, context);) 

        int returnStatus = response.getStatusLine().getStatusCode();

        switch (returnStatus)
        case 404:
            // deal with 404
        case 200:
            HttpEntity entity = response.getEntity();

            if (entity != null) 
                    entity = new BufferedHttpEntity(entity);
                    InputStream instream = entity.getContent();
                try
                    // deal with instream
                 finally 
                    instream.close();
                    // make sure everything is consumed
                    EntityUtils.consume(entity);
                
             else 
                // throw exception
            
        default:
            // weird codes
        
    

【问题讨论】:

【参考方案1】:

我不确定拥有这么多并发连接是否有意义。你有几个核心?也许你应该使用异步http客户端来防止线程争夺资源。

【讨论】:

【参考方案2】:

我的猜测是IdleConnectionMonitorThread 是罪魁祸首。它每 50 毫秒抓取一次池外观,有效地阻止了所有工作线程,这些线程大部分时间都在等待池锁,而不是做任何有用的事情。

连接监视器扫描池的频率应该不超过每 30 秒一次。如果您想限制总连接寿命,您应该使用池连接管理器的 TTL(生存时间)参数。

【讨论】:

以上是关于为啥 PoolingHttpClientConnectionManager 提供越来越慢的连接?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥 CAP 定理中的 RDBMS 分区不能容忍,为啥它可用?