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


84

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

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

http://www.opensubscriber.com/message/commons-httpclient-dev@jakarta.apache.org/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 ++ थ्रेड द्वारा समवर्ती रूप से एक्सेस किया जाएगा। मैं सोच रहा था, क्या इससे कोई प्रदर्शन समस्याएँ पैदा होंगी? क्या MultiThreadedHttpConnectionManager अपने थ्रेड सुरक्षित नीति को लागू करने के लिए लॉक-फ्री तंत्र का उपयोग कर रहा है?

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

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

[विधि बी]

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

क्या Conman.shutdown () प्रदर्शन समस्याओं से पीड़ित होगा?

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

जवाबों:


46

निश्चित रूप से विधि ए क्योंकि इसका जमाव और धागा सुरक्षित है।

यदि आप httpclient 4.x का उपयोग कर रहे हैं, तो कनेक्शन प्रबंधक को ThreadSafeClientConnManager कहा जाता है । आगे के विवरण के लिए इस लिंक को देखें (स्क्रॉल करके "पूलिंग कनेक्शन मैनेजर")। उदाहरण के लिए:

    HttpParams params = new BasicHttpParams();
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    ClientConnectionManager cm = new ThreadSafeClientConnManager(params, registry);
    HttpClient client = new DefaultHttpClient(cm, params);

49
ThreadSafeClientConnManager को 4.2 में पूलिंगक्लिएंटकॉन्मनमैन के पक्ष में पदावनत किया गया है
ड्रू स्टीफंस

नमस्ते, इस विधि द्वारा बनाई गई httpclient सत्र को बनाए रखने के लिए इस्तेमाल किया जा सकता है जैसा कि यहां बताया गया है stackoverflow.com/questions/5960832/… ...? क्योंकि जब मैंने कोशिश की, तो मैं अलग-अलग अनुरोधों के साथ सत्र को बनाए रखने में सक्षम नहीं था ...
11

17
4.3.1 यहाँ: PoolingClientConnManager को PoolingHttpClientConnManManager के पक्ष में पदावनत किया गया है।
माथियास

@DrewStephens ने फिर से PoolingClientConnManager को PoolingHttpClientConnectionManager के पक्ष में पदावनत कर दिया
didxga

18

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

अधिक जानकारी के लिए कृपया http://www.mail-archive.com/httpclient-users@hc.apache.org/msg02455.html देखें।


1
जब ग्राहक को वैश्विक बना दिया जाता है, तो कनेक्शन प्रबंधक पर कोई "शटडाउन" कॉल करेगा।
वैंड मेकर

1
कौन से उपकरण / लिनेक्स कमांड डिबग करने के लिए उपयोगी हैं या हुड के तहत कनेक्शनमैन के व्यवहार को "कल्पना" करते हैं? मैं पूछता हूं क्योंकि हमें वर्तमान में CLOSE_WAIT और अन्य प्रभावों के कनेक्शन से परेशानी है और हम यह देखने के लिए एक अच्छा तरीका ढूंढ रहे हैं कि वास्तव में क्या चल रहा है।
क्रिस्टोफ

@WandMaker मुझे पूरा यकीन है कि या तो प्रोग्राम बंद होने पर या जब आप काम के कुछ बैच के साथ समाप्त हो जाते हैं तो आपको शटडाउन कहेंगे जहाँ आपको कुछ समय के लिए किसी कनेक्शन की आवश्यकता नहीं होगी।
निकोलस डिपियाज़ा

1
@ क्रिसटोफ netstatउस पर बहुत अच्छा काम करता है। Technet.microsoft.com/en-us/sysinternals/bb897437.aspx भी
निकोलस डायपियाज़ा

13

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

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 समस्या से नहीं टकराएगा। यह दृष्टिकोण मानता है कि प्रत्येक धागा लंबे समय तक कनेक्शन पर लटका नहीं है। ध्यान दें कि कॉनमैन खुद को खुला छोड़ दिया गया है।


मेरे सवाल का वास्तविक जवाब नहीं दिया, किस पद्धति (ए या बी) पर बेहतर है।
चोक यान चेंग

5

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

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

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


1
उफ़। HttpClient 3.x से 4.x पर माइग्रेट करने की कोई योजना नहीं है, क्योंकि 3.x मेरे आवेदन में लगभग ~ 2 साल से निर्दोष चल रहा था :)
Cheok Yan Cheng

9
यकीन है, बस अगर कोई और यहाँ एक जवाब के लिए Googling आया :)
थॉमस Ahle

4

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

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.