Durante un tiempo, he estado usando HttpClient en un entorno multiproceso. Para cada hilo, cuando inicia una conexión, creará una instancia de HttpClient completamente nueva.
Recientemente, descubrí que, al usar este enfoque, puede hacer que el usuario tenga demasiados puertos abiertos y la mayoría de las conexiones estén en estado TIME_WAIT.
http://www.opensubscriber.com/message/[email protected]/86045.html
Por lo tanto, en lugar de hacer cada hilo:
HttpClient c = new HttpClient();
try {
c.executeMethod(method);
}
catch(...) {
}
finally {
method.releaseConnection();
}
Planeamos tener:
[MÉTODO A]
// global_c is initialized once through
// HttpClient global_c = new HttpClient(new MultiThreadedHttpConnectionManager());
try {
global_c.executeMethod(method);
}
catch(...) {
}
finally {
method.releaseConnection();
}
En una situación normal, 50 ++ subprocesos accederán simultáneamente a global_c. Me preguntaba, ¿esto creará problemas de rendimiento? ¿MultiThreadedHttpConnectionManager utiliza un mecanismo sin bloqueo para implementar su política segura para subprocesos?
Si 10 subprocesos utilizan global_c, ¿se bloquearán los otros 40 subprocesos?
¿O sería mejor si, en cada hilo, creo una instancia de un HttpClient, pero libero el administrador de conexión explícitamente?
[MÉTODO B]
MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManager();
HttpClient c = new HttpClient(connman);
try {
c.executeMethod(method);
}
catch(...) {
}
finally {
method.releaseConnection();
connman.shutdown();
}
¿Connman.shutdown () sufrirá problemas de rendimiento?
¿Puedo saber qué método (A o B) es mejor para la aplicación con hilos 50 ++?
fuente
El método A es recomendado por la comunidad de desarrolladores de httpclient.
Consulte http://www.mail-archive.com/[email protected]/msg02455.html para obtener más detalles.
fuente
netstat
hace un buen trabajo en eso. technet.microsoft.com/en-us/sysinternals/bb897437.aspx tambiénMi lectura de los documentos es que HttpConnection en sí no se trata como seguro para subprocesos y, por lo tanto, MultiThreadedHttpConnectionManager proporciona un grupo reutilizable de HttpConnections, tiene un único MultiThreadedHttpConnectionManager compartido por todos los subprocesos y se inicializa exactamente una vez. Entonces necesita un par de pequeños refinamientos a la opción A.
MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManag
Luego, cada hilo debe usar la secuencia para cada solicitud, obtener una conexión del grupo y volver a colocarla al finalizar su trabajo; usar un bloque final puede ser bueno. También debe codificar la posibilidad de que el grupo no tenga conexiones disponibles y procesar la excepción de tiempo de espera.
HttpConnection connection = null try { connection = connman.getConnectionWithTimeout( HostConfiguration hostConfiguration, long timeout) // work } catch (/*etc*/) {/*etc*/} finally{ if ( connection != null ) connman.releaseConnection(connection); }
Como está utilizando un grupo de conexiones, en realidad no cerrará las conexiones y, por lo tanto, esto no debería afectar al problema TIME_WAIT. Este enfoque supone que cada hilo no se aferra a la conexión por mucho tiempo. Tenga en cuenta que el propio estafador se deja abierto.
fuente
Creo que querrás usar ThreadSafeClientConnManager.
Puedes ver cómo funciona aquí: http://foo.jasonhudgins.com/2009/08/http-connection-reuse-in-android.html
O en el
AndroidHttpClient
que lo usa internamente.fuente
Con HttpClient 4.5 puede hacer esto:
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(new PoolingHttpClientConnectionManager()).build();
Tenga en cuenta que este implementa Closeable (para cerrar el administrador de conexiones).
fuente