Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTPClient 4.x Connection reuse not happening

I tried the following example of Apache http client:

http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientMultiThreadedExecution.java

I set the max pool size as 5 and run ten threads. After running this code, when I check netstat , I see 10 TCP connections being open. I was expecting the connections to be reused. Why is this ? Am I missing something ?

Code snippet is as below:

public class ClientMultiThreadedExecution {
public static void main(String[] args) throws Exception {

    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(
    new Scheme("http", 18080, PlainSocketFactory.getSocketFactory()));

    ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry);
    cm.setDefaultMaxPerRoute(5);
    cm.setMaxTotal(5);


    HttpClient httpclient = new DefaultHttpClient(cm);
    try {
        // create an array of URIs to perform GETs on
        String uri = "http://test.webservice.com:18080/TestServlet";
        String data = "This is a test message";

        System.out.println("Started at: " + new Date());
        // creating 10 threads
        PostThread[] threads = new PostThread[10];

        for (int i = 0; i < threads.length; i++) {
        HttpPost httpPost = new HttpPost(uri);
        threads[i] = new PostThread(httpclient, httpPost, data, i + 1);
            threads[i].start();
            //Thread.sleep(1000);
        }

       // join the threads
        for (int j = 0; j < threads.length; j++) {
            threads[j].join();
        }

    } finally {
        // When HttpClient instance is no longer needed,
        // shut down the connection manager to ensure
        // immediate deallocation of all system resources
        System.out.println("Ended at: " + new Date());
        httpclient.getConnectionManager().shutdown();
    }
}

/**
 * A thread that performs a POST.
 */
static class PostThread extends Thread {

    private final HttpClient httpClient;
    private final HttpContext context;
    private final HttpPost httpPost;
    private final int id;
    private final String data;

    public PostThread(HttpClient httpClient, HttpPost httpPost, String data, int id) {
        this.httpClient = httpClient;
        this.context = new BasicHttpContext();
        this.httpPost = httpPost;
        this.id = id;
        this.data = data;
    }

    /**
     * Executes the PostMethod and prints some status information.
     */
    @Override
    public void run() {

        //System.out.println(id + " - about to get something from " + httpPost.getURI());

        try {

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
            nameValuePairs.add(new BasicNameValuePair("XML",data));
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs,"UTF-8"));

            // execute the method
            HttpResponse response = httpClient.execute(httpPost, context);

            //System.out.println(id + " - get executed");
            // get the response body as an array of bytes
            if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
                System.out.println("Success");

            //Is this step necessary ?? Need to check as only status code is required
            //httpPost.abort();
            //HttpEntity entity = response.getEntity();

            //And this ?
            //EntityUtils.consume(entity);

        } catch (Exception e) {
            httpPost.abort();
            System.out.println(id + " - error: " + e);
        }
    }

}}
like image 211
Dunxton Avatar asked Nov 20 '11 07:11

Dunxton


People also ask

Do we need to close HttpClient connection?

If you are processing HTTP responses manually instead of using a response handler, you need to close all the http connections by yourself.

Is Apache HttpClient deprecated?

From Apache HTTP Client API version 4.3 on wards, DefaultHttpClient is deprecated.

Is HttpClient multithreaded?

HttpClient is fully thread-safe when used with a thread-safe connection manager such as MultiThreadedHttpConnectionManager.


1 Answers


        //Is this step necessary ?? Need to check as only status code is required
        //httpPost.abort();
        //HttpEntity entity = response.getEntity();

        //And this ?
        //EntityUtils.consume(entity);

Guess what? It is.

One MUST ensure response content gets consumed in order to have the underlying connection released back to the connection manager. Invocation of either EntityUtils#consume or httpUriRequest#abort triggers release of connection back to the pool. The difference is that the former attempts to keep the connection alive while the latter does not.

like image 64
ok2c Avatar answered Oct 17 '22 22:10

ok2c