2011-01-14 39 views
4

讓我解釋一下情況。用Httpclient 4.0.3隨機掛多帖

我有一個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並通過執行發送它,所有requiered參數和這樣的三重驗證。

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)正確處理。基本上返回一些params和我在我的頁面上打印的一個小gif。

但是,一旦我開始壓力測試我的應用程序,即在4-5個選項卡中加載相同的頁面,我的應用程序似乎隨機掛起,每當我在同一時間執行多個POST。我想即使我使用相同的HttpClient對象因爲我正確地宣佈我的ThreadSafeClientConnManager(我想?)我不會有任何問題,所以它應該處理多個線程。

任何人都知道我在做什麼錯了?如果我加1我的標籤1,它不掛。正當我同時刷新多個標籤時。

任何有線索? :S(SRY英語的心不是我的第一語言^^;)

回答

2

你可能想從HttpClient API看看這個 -

ThreadSafeClientConnManager保持每一路徑基礎並在連接的最大限制總。默認情況下,此實現將爲每條給定路由創建不超過2個併發連接,總共不會超過20個連接。對於許多真實世界的應用程序來說,這些限制可能會被證明過於嚴格,特別是如果他們使用HTTP作爲其服務的傳輸協議。但是,連接限制可以使用HTTP參數進行調整。

也許您的應用程序耗盡池連接,並且您需要增加池大小。

3

@Apache範,設定這樣的:

ConnManagerParams.setMaxTotalConnections(cm_params,200); connPerRoute.setDefaultMaxPerRoute(50);

懷疑我能跑出連接,我打開3-4選項卡,並運行了...這可能是每個標籤4 POST,所以這不加起來:S

+0

這很好地解決了我有一個非常類似的症狀的問題。 – 2012-09-26 16:30:03

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"); 
     } 
    }); 
0

我被困到了同樣的錯誤。我們注意到HttpClient並沒有關閉它自己。

我所做的是,我在我未清理的HttpClient和HttpResponse上嘗試了HttpClientUtils.closeQuietly()方法。它幫助我的事業,並且它停止了再繼續。你也可以試試它。