随机悬挂Httpclient 4.0.3的多个帖子

时间:2011-01-14 18:13:05

标签: java httpclient

让我解释一下情况。

我有一个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不是我的第一语言^^;)

4 个答案:

答案 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()方法。它帮助了我的事业,它再次停止了。您也可以尝试使用它。