Best practices for using HttpClient in a multi-threaded environment

For a while I used HttpClient in a multi-threaded environment. For each thread, when it initiates a connection, it will create a completely new instance of HttpClient.

I recently discovered that with this approach, a user can open too many ports, and most connections are in TIME_WAIT state.

http://www.opensubscriber.com/message/commons-httpclient-dev@jakarta.apache.org/86045.html

Therefore, instead of each thread, do:

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

We are planing:

[METHOD A]

 // global_c is initialized once through // HttpClient global_c = new HttpClient(new MultiThreadedHttpConnectionManager()); try { global_c.executeMethod(method); } catch(...) { } finally { method.releaseConnection(); } 

In a normal situation, global_c will be available simultaneously with 50 ++ threads. I was wondering if this would create any performance issues? Is MultiThreadedHttpConnectionManager using a locking mechanism to implement thread safety policies?

If 10 threads use global_c, will the remaining 40 threads be blocked?

Or would it be better if I created an HttpClient instance in each thread but explicitly freed up the connection manager?

[METHOD B]

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

Will connman.shutdown () suffer from performance issues?

Can I find out which method (A or B) is better for an application using 50 ++ streams?

+80
Aug 15 '09 at 5:13
source share
5 answers

Method A is recommended by the httpclient community.

See http://www.mail-archive.com/httpclient-users@hc.apache.org/msg02455.html for more details.

+16
Aug 29 '09 at 15:35
source

Definitely method A, because its combined and thread safe.

If you are using httpclient 4.x, the connection manager is called ThreadSafeClientConnManager . See this link for more details (scroll down to "Connect Connection Manager"). For example:

  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); 
+41
Sep 23 '10 at 21:11
source

My reading of the docs is that the HttpConnection itself is not considered thread safe, and therefore the MultiThreadedHttpConnectionManager provides a reusable HttpConnections pool, you have one MultiThreadedHttpConnectionManager that is common to all threads and initialized exactly once. Therefore, you need a few small refinements in option A.

 MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManag 

Then each thread should use a sequence for each request, get a connection from the pool and return it after completing its work - using the finally block can be good. You must also indicate that the pool does not have connections available and is handling a timeout exception.

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

Since you are using the connection pool, you are not actually closing the connections, and therefore this should not affect the TIME_WAIT problem. This approach suggests that each thread does not communicate for a long time. Note that conman itself remains open.

+12
Aug 15 '09 at 6:09
source

I think you will want to use ThreadSafeClientConnManager.

You can see how it works here: http://foo.jasonhudgins.com/2009/08/http-connection-reuse-in-android.html

Or in AndroidHttpClient , which uses it internally.

+5
Aug 13 '10 at
source

With HttpClient 4.5 you can do this:

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

Note that this tool implements Closeable (to close the connection manager).

0
Oct 09 '17 at 20:00
source



All Articles