2011-11-20 57 views
6

我試過的Apache HTTP客戶端下面的例子:了HTTPClient 4.x的連接重用沒有發生

http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientMultiThreadedExecution.java

我設定的最大池大小爲5和跑十個線程。運行此代碼後,當我檢查netstat時,發現有10個TCP連接處於打開狀態。我期待着連接被重用。爲什麼是這樣 ?我錯過了什麼嗎?

代碼片段如下:

public class ClientMultiThreadedExecution { 
public static void main(String[] args) throws Exception { 

    SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    schemeRegistry.register(
    new Scheme("http", 18080, PlainSocketFactory.getSocketFactory())); 

    ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry); 
    cm.setDefaultMaxPerRoute(5); 
    cm.setMaxTotal(5); 


    HttpClient httpclient = new DefaultHttpClient(cm); 
    try { 
     // create an array of URIs to perform GETs on 
     String uri = "http://test.webservice.com:18080/TestServlet"; 
     String data = "This is a test message"; 

     System.out.println("Started at: " + new Date()); 
     // creating 10 threads 
     PostThread[] threads = new PostThread[10]; 

     for (int i = 0; i < threads.length; i++) { 
     HttpPost httpPost = new HttpPost(uri); 
     threads[i] = new PostThread(httpclient, httpPost, data, i + 1); 
      threads[i].start(); 
      //Thread.sleep(1000); 
     } 

     // join the threads 
     for (int j = 0; j < threads.length; j++) { 
      threads[j].join(); 
     } 

    } finally { 
     // When HttpClient instance is no longer needed, 
     // shut down the connection manager to ensure 
     // immediate deallocation of all system resources 
     System.out.println("Ended at: " + new Date()); 
     httpclient.getConnectionManager().shutdown(); 
    } 
} 

/** 
* A thread that performs a POST. 
*/ 
static class PostThread extends Thread { 

    private final HttpClient httpClient; 
    private final HttpContext context; 
    private final HttpPost httpPost; 
    private final int id; 
    private final String data; 

    public PostThread(HttpClient httpClient, HttpPost httpPost, String data, int id) { 
     this.httpClient = httpClient; 
     this.context = new BasicHttpContext(); 
     this.httpPost = httpPost; 
     this.id = id; 
     this.data = data; 
    } 

    /** 
    * Executes the PostMethod and prints some status information. 
    */ 
    @Override 
    public void run() { 

     //System.out.println(id + " - about to get something from " + httpPost.getURI()); 

     try { 

      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1); 
      nameValuePairs.add(new BasicNameValuePair("XML",data)); 
      httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs,"UTF-8")); 

      // execute the method 
      HttpResponse response = httpClient.execute(httpPost, context); 

      //System.out.println(id + " - get executed"); 
      // get the response body as an array of bytes 
      if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) 
       System.out.println("Success"); 

      //Is this step necessary ?? Need to check as only status code is required 
      //httpPost.abort(); 
      //HttpEntity entity = response.getEntity(); 

      //And this ? 
      //EntityUtils.consume(entity); 

     } catch (Exception e) { 
      httpPost.abort(); 
      System.out.println(id + " - error: " + e); 
     } 
    } 

}} 
+1

的解決方案是特別提到的協議版本作爲HTTP_1_1:'HttpProtocolParams.setVersion(參數,可以HttpVersion.HTTP_1_1);'。然後池塘工作。 – Dunxton

+0

我們需要用什麼來代替參數意味着什麼價值以及我們需要在代碼中放置這個語句 – Labeo

回答

11

 //Is this step necessary ?? Need to check as only status code is required 
     //httpPost.abort(); 
     //HttpEntity entity = response.getEntity(); 

     //And this ? 
     //EntityUtils.consume(entity); 

你猜怎麼着?它是。

一個必須確保響應內容被消耗,以便將底層連接釋放回連接管理器。調用EntityUtils#consumehttpUriRequest#abort會觸發釋放連接回池。不同之處在於,前者試圖保持連接存活,而後者則不存在。

在這個碼
+0

這個代碼塊怎麼樣? catch(例外e){http:// httpPost.abort(); System.out.println(id +「 - error:」+ e); '每當發生異常時,調用httpPost.abort()。然而,我觀察到的是,同樣的中止連接仍然被分發給其他線程,並且所有這些連接都出現錯誤信息'java.io.IOException:請求已中止'。爲什麼會發生? – Dunxton

+2

@鄧克斯頓中止的連接立即被丟棄並從池中逐出。您正嘗試重新使用中止的請求。不要那樣做。請求對象很便宜。 – oleg

相關問題