为什么PoolingHttpClientConnectionManager提供越来越慢的连接?

时间:2015-03-19 21:29:18

标签: java http httpclient apache-httpclient-4.x

我使用 httpClient 4.3.6 CloseableHttpClientPoolingHttpClientConnectionManager投放。

我当前的设置包括200个线程,通过客户端同时执行G​​ET请求。我试图最大化线程每秒可以处理的请求数,但是一旦我开始执行超过~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
        }
    }

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

连接监视器可能不会频繁地扫描池,而不是每30秒一次。如果要限制总连接生命周期,则应使用池化连接管理器的TTL(生存时间)参数。