2011-11-20 19 views
6

नहीं हो रहा पुनः उपयोग मैं Apache HTTP ग्राहक के निम्न उदाहरण की कोशिश की:httpclient 4.x कनेक्शन

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

मैं 5 के रूप में अधिकतम पूल आकार सेट और दस धागे चलाते हैं। इस कोड को चलाने के बाद, जब मैं नेटस्टैट की जांच करता हूं, तो मुझे 10 टीसीपी कनेक्शन खुलते हैं। मैं कनेक्शन का पुन: उपयोग करने की उम्मीद कर रहा था। ऐसा क्यों है ? क्या मैं कुछ भूल रहा हूँ ?

कोड स्निपेट के रूप में नीचे है:

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#consume या httpUriRequest#abort का आमंत्रण पूल में कनेक्शन की रिहाई को ट्रिगर करता है। अंतर यह है कि पूर्ववर्ती कनेक्शन को जीवित रखने के पूर्व प्रयास करते हैं।

+0

में इस कथन को रखने के लिए हमें क्या मूल्य और कहां रखने की आवश्यकता है? 'पकड़ो (अपवाद ई) { httpPost.abort(); System.out.println (आईडी + "- त्रुटि:" + ई); } 'जब भी कोई अपवाद होता है, httpPost.abort() को कॉल किया जाता है। हालांकि, मैं जो देखता हूं वह यह है कि, उसी निरस्त कनेक्शन को अभी भी अन्य धागे को सौंप दिया जा रहा है और उनमें से सभी संदेश 'java.io.IOException: अनुरोध पहले ही निरस्त कर दिया गया है' के साथ त्रुटि हो रही है। ऐसा क्यों होता है ? – Dunxton

+2

@ डंकस्टन अपरिवर्तित कनेक्शन तुरंत पूल से त्याग और बेदखल हो जाते हैं। आप निरस्त अनुरोध का पुन: उपयोग करने का प्रयास कर रहे हैं। ऐसा मत करो। अनुरोध वस्तुओं सस्ते हैं। – oleg

संबंधित मुद्दे