You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by Vikram <al...@yahoo.com> on 2014/01/13 19:17:25 UTC

PoolingHttpClientConnectionManager is not reusing connection

I am using HttpClient 4.3.1. 

Using HttpClient with PoolingHttpClientConnectionManager as the
connection manager. I have also set MaxTotal as 5000 and MaxPerRoute as
4000. When I am load testing it, I notice that when a connection is created,
it is leased from the pool and when the POST message execute() is done, it
does NOT put the connection back into ConnectionPool's available queue. 

This causes new connection for every request and overtime all my ephemeral
client ports are exhausted. 

Code Snippet:
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
                .<ConnectionSocketFactory> create()
                .register("https", sslConnectionSocketFactory)
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .build();
        
        pollingConnectionManager = new
PoolingHttpClientConnectionManager(socketFactoryRegistry);
        pollingConnectionManager.setMaxTotal(5000);
        pollingConnectionManager.setDefaultMaxPerRoute(4000);

       RequestConfig defaultRequestConfig = RequestConfig.custom().build();
        
        httpClient = HttpClients.custom()
                        .setConnectionManager(pollingConnectionManager) 
                        .setDefaultRequestConfig(defaultRequestConfig)
                        .setConnectionReuseStrategy(new
DefaultConnectionReuseStrategy())
                        .build();

        HttpPost httpPost = new HttpPost(contactUri);
        ByteArrayEntity entity = new ByteArrayEntity(data);
        httpPost.setEntity(entity);
        httpPost.setHeader("Content-Type", "application/json");
        
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpPost, new BasicHttpContext());
        } catch (HttpResponseException ex) {
            logger.debug("Error while notifying to external service,
statuscode {}, Exception {}", ex.getStatusCode(), 
                    Throwables.getStackTraceAsString(ex));
        } catch (ClientProtocolException e) {
            logger.error("Exception while notifying to {}, Exception :
{}",contactUri, Throwables.getStackTraceAsString(e));
        } catch (Exception e) {
           logger.error("Exception while notifying to {}, Exception :
{}",contactUri, Throwables.getStackTraceAsString(e));
    } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    // Log it
                }
            }
        }

In HttpClient, MainClientExec class, I see this code 
         if (entity == null || !entity.isStreaming()) {
                // connection not needed and (assumed to be) in re-usable
state
                connHolder.releaseConnection();
                return Proxies.enhanceResponse(response, null);
           } else {
                return Proxies.enhanceResponse(response, connHolder);
           }

I see that entity.isStreaming() always returns true, and the connection is
never released.


Any help in this issue would be much appreciated.

Thanks,
-Vikram



--
View this message in context: http://httpcomponents.10934.n7.nabble.com/PoolingHttpClientConnectionManager-is-not-reusing-connection-tp22152.html
Sent from the HttpClient-User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org


Re: PoolingHttpClientConnectionManager is not reusing connection

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Mon, 2014-01-13 at 10:17 -0800, Vikram wrote:
> I am using HttpClient 4.3.1. 
> 
> Using HttpClient with PoolingHttpClientConnectionManager as the
> connection manager. I have also set MaxTotal as 5000 and MaxPerRoute as
> 4000. When I am load testing it, I notice that when a connection is created,
> it is leased from the pool and when the POST message execute() is done, it
> does NOT put the connection back into ConnectionPool's available queue. 
> 
> This causes new connection for every request and overtime all my ephemeral
> client ports are exhausted. 
> 
> Code Snippet:
> Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
>                 .<ConnectionSocketFactory> create()
>                 .register("https", sslConnectionSocketFactory)
>                 .register("http", PlainConnectionSocketFactory.INSTANCE)
>                 .build();
>         
>         pollingConnectionManager = new
> PoolingHttpClientConnectionManager(socketFactoryRegistry);
>         pollingConnectionManager.setMaxTotal(5000);
>         pollingConnectionManager.setDefaultMaxPerRoute(4000);
> 
>        RequestConfig defaultRequestConfig = RequestConfig.custom().build();
>         
>         httpClient = HttpClients.custom()
>                         .setConnectionManager(pollingConnectionManager) 
>                         .setDefaultRequestConfig(defaultRequestConfig)
>                         .setConnectionReuseStrategy(new
> DefaultConnectionReuseStrategy())
>                         .build();
> 
>         HttpPost httpPost = new HttpPost(contactUri);
>         ByteArrayEntity entity = new ByteArrayEntity(data);
>         httpPost.setEntity(entity);
>         httpPost.setHeader("Content-Type", "application/json");
>         
>         CloseableHttpResponse response = null;
>         try {
>             response = httpClient.execute(httpPost, new BasicHttpContext());
>         } catch (HttpResponseException ex) {
>             logger.debug("Error while notifying to external service,
> statuscode {}, Exception {}", ex.getStatusCode(), 
>                     Throwables.getStackTraceAsString(ex));
>         } catch (ClientProtocolException e) {
>             logger.error("Exception while notifying to {}, Exception :
> {}",contactUri, Throwables.getStackTraceAsString(e));
>         } catch (Exception e) {
>            logger.error("Exception while notifying to {}, Exception :
> {}",contactUri, Throwables.getStackTraceAsString(e));
>     } finally {
>             if (response != null) {
>                 try {
>                     response.close();
>                 } catch (IOException e) {
>                     // Log it
>                 }
>             }
>         }
> 
> In HttpClient, MainClientExec class, I see this code 
>          if (entity == null || !entity.isStreaming()) {
>                 // connection not needed and (assumed to be) in re-usable
> state
>                 connHolder.releaseConnection();
>                 return Proxies.enhanceResponse(response, null);
>            } else {
>                 return Proxies.enhanceResponse(response, connHolder);
>            }
> 
> I see that entity.isStreaming() always returns true, and the connection is
> never released.
> 
> 
> Any help in this issue would be much appreciated.
> 
> Thanks,
> -Vikram
> 

Connections are likely not to be re-used because they carry some state
(SSL identity in your case). For details see:

http://hc.apache.org/httpcomponents-client-4.3.x/tutorial/html/advanced.html#stateful_conn

If you want those connections re-used either disable connection state
tracking or make sure all related requests share the same context. 

Oleg


---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org