أفضل الممارسات لاستخدام httpclient في بيئة متعددة المراحل

StackOverflow https://stackoverflow.com/questions/1281219

  •  16-09-2019
  •  | 
  •  

سؤال

لفترة من الوقت، كنت أستخدم 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();
}

نحن نخطط للحصول على:

طريقة A

// 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 خيوط تستخدم Global_c، هل سيتم تأمين المواضيع الأربعين الأخرى؟

أو سيكون أفضل إذا، في كل موضوع، أقوم بإنشاء مثيل ل httpclient، ولكن حرر مدير الاتصال صراحة؟

طريقة ب

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

سوف Connman.Shutdown () تعاني قضايا الأداء؟

هل لي أن أعرف الطريقة (A أو B) أفضل، للتطبيق باستخدام مؤشرات الترابط 50 ++؟

هل كانت مفيدة؟

المحلول 2

الطريقة الأولى يوصى به من قبل مجتمع مطور httpclient.

يرجى الرجوع http://www.mail-archive.com/httpclient-users@hc.apache.org/msg02455.html لمزيد من التفاصيل.

نصائح أخرى

بالتأكيد الطريقة a لأنها آمنة المجمعة والخيط.

إذا كنت تستخدم HTTPClient 4.x، يسمى إدارة الاتصال showafeclientconnager.. وبعد انظر الى هذا حلقة الوصل لمزيد من التفاصيل (قم بالتمرير لأسفل إلى "إدارة اتصال التجميع"). علي سبيل المثال:

    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);

قرية المستندات هي أن HttpConnection نفسها لا يتم التعامل معها كأمأ من الخيط، وبالتالي يوفر multithreadedhttpconnectionmanagermanager مجموعة قابلة لإعادة الاستخدام من httpconnections، لديك مجموعة واحدة multithreaddhttpconnectionmanager مشترك من قبل جميع المواضيع وأعيدت بالضبط مرة واحدة. لذلك تحتاج إلى بعض التحسينات الصغيرة للخيار 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. هذا النهج لا يشير إلى أن كل موضوع لا يتعطل على الاتصال لفترة طويلة. لاحظ أن كونتمان نفسه قد ترك مفتوحا.

أعتقد أنك سوف ترغب في استخدام الخناطيسين

يمكنك أن ترى كيف يعمل هنا: http://foo.jasonhudgins.com/2009/08/http-connection-reuse-in-android.html.

أو في AndroidHttpClient الذي يستخدمه داخليا.

مع HTTPClient 4.5 يمكنك القيام بذلك:

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

لاحظ أن هذا ينفذ قريبا (لإيقاف تشغيل إدارة الاتصال).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top