这些天我正在努力解决关于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的源代码我没有看到有关此代码的相关差异。
任何想法的人?
答案 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();