HttpPut在多线程环境中与Apache HttpClient的性能

时间:2014-06-19 15:54:37

标签: java multithreading performance httpclient

这些天我正在努力解决关于Apache HttpClient和线程的一个非常奇怪的问题。

关键是我有一个由所有线程共享的HttpClient,并使用它来执行HttpPut请求来上传一个小文件(8k aprox。)。好吧,少量的线程一切都很好,时间也很好(200-600毫秒),但是当我们开始增加并发线程数时,时间很糟糕(8秒)。

我们检查了服务器以确保问题不存在。使用具有相同负载的jmeter(一秒钟内1000个线程),我们得到的响应时间为毫秒!!

实现使用线程安全的连接管理器:

PoolingHttpClientConnectionManager httpConnectionManager = new PoolingHttpClientConnectionManager();
httpConnectionManager.setMaxTotal(5000);
httpConnectionManager.setDefaultMaxPerRoute(5000);

HttpClient httpClient = HttpClientBuilder.create()
     .setConnectionManager(httpConnectionManager)
     .build();

线程运行以下代码:

HttpPut put = new HttpPut(urlStr);
put.setConfig(RequestConfig.custom()
     .setExpectContinueEnabled(true)
     .setStaleConnectionCheckEnabled(false)
     .setRedirectsEnabled(true).build());
put.setEntity(new FileEntity(new
            File("image.tif")));
put.setHeader("Content-Type", "image/tiff");
put.setHeader("Connection", "keep-alive");

HttpResponse response = httpClient.execute(put, HttpClientContext.create());

看起来好像有一个共享资源在负载很高时会产生巨大影响。

查看Apache Jmeter的源代码我没有看到有关此代码的相关差异。

任何想法的人?

1 个答案:

答案 0 :(得分:0)

您需要在客户端启用调试才能执行以下操作:

验证5000的池实际上是用于深度。记录器将显示“可用保留在池中”的更改总计以及正在使用的当前池条目的编号。

验证您是否立即清理并返回以汇集条目。请记住关闭资源(用于访问响应的流,实体对象)

  CloseableHttpResponse response
    case PUT:
        HttpPut httpPut = new HttpPut(url);
        httpPut.setProtocolVersion(new ProtocolVersion("HTTP", 1,1));
        httpPut.setConfig(this.config);
        httpPut.setEntity(new StringEntity(data, ContentType.APPLICATION_JSON));                
        response = httpClient.execute(httpPut, context);
        httpPut.releaseConnection();

More info