java - मल्टीथ्रेडेड पर्यावरण में HttpClient का उपयोग करने के लिए सबसे अच्छा अभ्यास




apache-commons-httpclient (4)

थोड़ी देर के लिए, मैं एक बहुप्रचारित वातावरण में HttpClient का उपयोग कर रहा हूं। प्रत्येक थ्रेड के लिए, जब यह कनेक्शन शुरू करता है, तो यह एक बिल्कुल नया एचटीपी क्लाइंट उदाहरण बना देगा।

हाल ही में, मैंने पाया है कि, इस दृष्टिकोण का उपयोग करके, यह उपयोगकर्ता को कई बंदरगाहों को खोला जा सकता है, और अधिकांश कनेक्शन TIME_WAIT स्थिति में हैं।

http://www.opensubscriber.com/message/[email protected]/86045.html

इसलिए, प्रत्येक थ्रेड के बजाय:

HttpClient c = new HttpClient();
try {
    c.executeMethod(method);
}
catch(...) {
}
finally {
    method.releaseConnection();
}

हम योजना बनाने की योजना बना रहे हैं:

[विधि ए]

// global_c is initialized once through
// HttpClient global_c = new HttpClient(new MultiThreadedHttpConnectionManager());

try {
    global_c.executeMethod(method);
}
catch(...) {
}
finally {
    method.releaseConnection();
}

एक सामान्य स्थिति में, global_c को 50 ++ धागे द्वारा समवर्ती रूप से उपयोग किया जाएगा। मैं सोच रहा था, क्या यह कोई प्रदर्शन समस्या पैदा करेगा? क्या यह थ्रेड सुरक्षित नीति को लागू करने के लिए एक लॉक-फ्री तंत्र का उपयोग कर मल्टी थ्रेडेड हैट्पकनेक्शन मैनेजर है?

यदि 10 धागे global_c का उपयोग कर रहे हैं, तो क्या अन्य 40 धागे बंद हो जाएंगे?

या बेहतर होगा अगर, प्रत्येक थ्रेड में, मैं एक HttpClient का एक उदाहरण बना देता हूं, लेकिन कनेक्शन प्रबंधक को स्पष्ट रूप से रिलीज़ करता हूं?

[विधि बी]

MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManager();
HttpClient c = new HttpClient(connman);
try {
      c.executeMethod(method);
}
catch(...) {
}
finally {
    method.releaseConnection();
    connman.shutdown();
}

Connman.shutdown () प्रदर्शन मुद्दों भुगतना होगा?

क्या मुझे पता है कि 50 ++ धागे का उपयोग कर आवेदन के लिए कौन सी विधि (ए या बी) बेहतर है?


HttpClient 4.5 के साथ आप यह कर सकते हैं:

CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(new PoolingHttpClientConnectionManager()).build();

ध्यान दें कि यह बंद करने योग्य (कनेक्शन प्रबंधक को बंद करने के लिए) लागू करता है।


दस्तावेज़ों का मेरा पठन यह है कि HttpConnection को स्वयं को थ्रेड सुरक्षित के रूप में नहीं माना जाता है, और इसलिए मल्टी थ्रेडेड एचटीपीकनेक्शन मैनेजर एचटीपीकनेक्शन का एक पुन: प्रयोज्य पूल प्रदान करता है, आपके पास एक ही मल्टी थ्रेडेड एचटीपीकनेक्शन मैनेजर सभी धागे द्वारा साझा किया गया है और बिल्कुल एक बार शुरू किया गया है। तो आपको विकल्प ए के लिए कुछ छोटे परिशोधन की आवश्यकता है।

MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManag

फिर प्रत्येक धागे को प्रत्येक अनुरोध के अनुक्रम का उपयोग करना चाहिए, पूल से एक अनुमान प्राप्त करना और इसे अपने काम के पूरा होने पर वापस रखना चाहिए - आखिरकार ब्लॉक का उपयोग करना अच्छा हो सकता है। आपको इस संभावना के लिए भी कोड करना चाहिए कि पूल में कोई कनेक्शन उपलब्ध नहीं है और टाइमआउट अपवाद को संसाधित करता है।

HttpConnection connection = null
try {
    connection = connman.getConnectionWithTimeout(
                        HostConfiguration hostConfiguration, long timeout) 
    // work
} catch (/*etc*/) {/*etc*/} finally{
    if ( connection != null )
        connman.releaseConnection(connection);
}

चूंकि आप कनेक्शन के पूल का उपयोग कर रहे हैं, आप वास्तव में कनेक्शन बंद नहीं करेंगे और इसलिए यह TIME_WAIT समस्या को हिट नहीं करना चाहिए। यह दृष्टिकोण मानता है कि प्रत्येक थ्रेड लंबे समय तक कनेक्शन पर नहीं लटकता है। ध्यान दें कि कमान स्वयं ही खुला रहता है।


मुझे लगता है कि आप ThreadSafeClientConnManager का उपयोग करना चाहेंगे।

आप देख सकते हैं कि यह यहां कैसे काम करता है: http://foo.jasonhudgins.com/2009/08/http-connection-reuse-in-android.html

या AndroidHttpClient जो आंतरिक रूप से इसका उपयोग करता है।


विधि ए को httpclient डेवलपर समुदाय द्वारा अनुशंसित किया जाता है।

अधिक जानकारी के लिए कृपया http://www.mail-archive.com/[email protected]/msg02455.html देखें।





apache-commons-httpclient