让我解释一下情况。
我有一个servlet将传出的GET / POST重定向到另一个域(某种代理)上的另一个项目,其工作是处理它并返回一些东西(params和gif)。我使用HttpClient 4.0.3来做到这一点。
我的应用程序在启动时发送了多个GET / POST,因此我设置了一次ThreadSafeClientConnManager来以这种方式处理多个线程。
cm_params = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(cm_params, 200);
ConnPerRouteBean connPerRoute = new ConnPerRouteBean();
HttpHost localhost = new HttpHost("localhost");
connPerRoute.setMaxForRoute(new HttpRoute(localhost), 50);
ConnManagerParams.setMaxConnectionsPerRoute(cm_params, connPerRoute);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
cm = new ThreadSafeClientConnManager(cm_params, schemeRegistry);
然后我用这些参数创建一个新的HttpClient,它应该足以同时处理一堆请求。当然,我在 public void service()上为每个GET / POST执行此操作,但在创建它之后使用相同的Httpclient对象。
httpclient = new DefaultHttpClient(cm, cm_params);
之后我建立我的POST并通过执行发送它,包含所有必需的参数和三重验证。
HttpPost httpPost = new HttpPost(target+tmpString);
httpPost.setHeader("Host", request.getHeader("host"));
httpPost.setHeader("User-Agent", request.getHeader("user-agent"));
httpPost.setHeader("Accept-Encoding", request.getHeader("accept-encoding"));
httpPost.setHeader("Accept", request.getHeader("accept"));
..etc..
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(params);
urlEncodedFormEntity.setContentEncoding(HTTP.UTF_8);
httpPost.setEntity(urlEncodedFormEntity);
HttpResponse response = httpclient.execute(httpPost);
最后我读了流并处理实体......
OutputStream os = res.getOutputStream();
InputStream is = response.getEntity().getContent();
byte[] buf = new byte[1024];
for(int n;(n=is.read(buf))!=-1;)
{
os.write(buf, 0, n);
}
// Make sure to close
is.close();
os.close();
// Flush entities just in case
EntityUtils.consume(urlEncodedFormEntity);
EntityUtils.consume(response.getEntity());
urlEncodedFormEntity.getContent().close();
response.getEntity().getContent().close();
所以我的问题是,当我加载页面时代码运行得很好。正确处理了4个请求(1个GET,3个POST)。基本上返回我在页面上打印的一些参数和一个小gif。
但是,一旦我开始压力测试我的应用程序,I.E。在4-5个选项卡中加载相同的页面,每当我同时执行多个POST时,我的应用程序似乎随机挂起。我认为即使我使用相同的Httpclient对象也没有任何问题,因为我正确地声明了我的ThreadSafeClientConnManager(我认为?)所以它应该处理多个线程。
任何人都知道我做错了什么?如果我逐个加载我的标签,它就不会挂起。就在我同时刷新多个标签的时候。
有人有线索吗? :S(sry english不是我的第一语言^^;)
答案 0 :(得分:3)
@Apache Fan,设置此:
ConnManagerParams.setMaxTotalConnections(cm_params,200); connPerRoute.setDefaultMaxPerRoute(50);
怀疑我可以用完连接,我打开3-4选项卡,它用完了......每个标签可能有4个POST,所以不会加起来:S
答案 1 :(得分:2)
您可能希望从HttpClient API -
中查看此内容ThreadSafeClientConnManager基于每个路由和总计维护最大连接限制。默认情况下,此实现将为每个给定路由创建不超过2个并发连接,并且总共不再有20个连接。对于许多实际应用程序而言,这些限制可能过于严格,特别是如果它们使用HTTP作为其服务的传输协议。但是,可以使用HTTP参数调整连接限制。
也许你的应用程序用完了池连接,你需要增加池大小。
答案 2 :(得分:0)
最近我试图实现这个但是我遇到了一些新的问题,比如我第一次发送请求然后它发送没有cookie但是第二次httpContext自动添加cookie
但这是发送的标准方式,但有时您请求的服务器接受没有cookie,所以我使用了INTERCEPTOR。在第二次它删除了自动添加的cookie后,它工作正常请使用下面的httpClient
拦截器代码:
httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
@Override
public void process(HttpRequest request, HttpContext context)
throws HttpException, IOException {
LOG.info("***************** Entered My Interceptor ****************************");
Header[] headers = request.getAllHeaders();
for (Header eachHeader : headers) {
LOG.info("Headers -- Name: {}, Value: {} ",
eachHeader.getName(), eachHeader.getValue());
}
request.removeHeaders("Cookie");
}
});
答案 3 :(得分:0)
我遇到了同样的错误。我们注意到的是HttpClient并没有关闭自己。
我做的是,我在未清除的HttpClient和HttpResponse上尝试了HttpClientUtils.closeQuietly()方法。它帮助了我的事业,它再次停止了。您也可以尝试使用它。