HTTPClient 4.x Connection reuse does not occur

I tried the following Apache http client example:

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

I set the maximum pool size to 5 and start ten threads. After running this code, when I check netstat, I see 10 open TCP connections. I expected the connections to be reused. Why is this? Did I miss something?

The code snippet is as follows:

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); } } }} 
+6
source share
2 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.

One MUST ensure that the response content is consumed so that the underlying connection is released back to the connection manager. A call to either EntityUtils#consume or httpUriRequest#abort triggers the release of a connection to the pool. The difference is that the former tries to keep the connection alive until the latter does.

+11
source

Source: https://habr.com/ru/post/901925/


All Articles