version: 4.4.1
App Server: TomEE7
We use PoolingHttpClientConnectionManager with the following defaults:
* max total connections: 100,000
* default max per route: 50
we create the HttpClient and PoolingHttpClientConnectionManager as static
singletons at container startup.
private static Thread globalConnManagerThread;
private static CloseableHttpClient globalHttpClient;
static {
// create global pooling connection manager
globalConnManagerPool = new PoolingHttpClientConnectionManager(
registry
);
globalConnManagerPool.setDefaultMaxPerRoute(50);
globalConnManagerPool.setMaxTotal(100000);
// create global HttpClient instance
final HttpClientBuilder builder = HttpClients.custom()
.setConnectionManager(globalConnManagerPool)
.setConnectionManagerShared(true)
.setConnectionTimeToLive(5, TimeUnit.MINUTES)
.setDefaultConnectionConfig(connConfig)
.setDefaultRequestConfig(requestConfig)
.setMaxConnPerRoute(50) // <<== default per route is 50
.setDefaultSocketConfig(socketConfig)
.setMaxConnTotal(100000)
.setRetryHandler(httpRetryHandler)
.useSystemProperties()
;
CloseableHttpClient globalHttpClient = builder.build();
}
We set the max per specific route with the following code snippet:
@PostConstruct public void init() {
List<URL> allUrls = getAllUrls();
for(final URL url : allUrls) {
HttpServiceConfig hsc = getHttpServiceConfig(url);
final String host = url.getHost();
final int portNo = url.getPort() == -1 ? url.getDefaultPort() :
url.getPort();
final String protocol = url.getProtocol();
final HttpHost httpHost = new HttpHost(host, portNo, protocol);
final HttpRoute httpRoute = new HttpRoute(httpHost);
globalConnManagerPool.setMaxPerRoute(httpRoute, 200); // <<== max set
to 200 for route
log.info(gMarker, "set route max-conns:"
+ "; max-allowed=" + hsc.getMaxConns()
+ "; protocol-host-port=" + protocol + "://" + host + ":" + portNo
+ "; httpRoute=" + String.valueOf(httpRoute)
);
}
}
we see each route specific max connection log message at startup. for instance:
set route max-conns: conns-max=200; protocol-host-port=https://some-host:443;
httpRoute={}->https://some-host:443
we have a background thread that monitors the apache-hc connection pool
statistics and emits log messages. we see the following apache-hc connection
manager pool “route specific” statistics logged:
private void logPoolStats() {
Set<HttpRoute> routes = globalConnManagerPool.getRoutes();
for(final HttpRoute r : routes) {
final PoolStats ps = cm.getStats(r);
final int available = ps.getAvailable();
final int active = ps.getLeased();
final int limit = ps.getMax();
final int blocking = ps.getPending();
String s = "emit statistic:"
+ " type=hc-conn-pool"
+ "; route=" + hostname
+ "; available=" + available
+ "; active=" + active
+ "; blocking=" + blocking
+ "; max-allowed=" + limit
+ "; server-nm=" + Helpers.getLocalHost() + ":" +
Helpers.getServerHttpsPort()
;
log.info(marker, s);
}
}
we see log messages like the following from the apache-hc connection pool
monitor logging:
emit statistic: type=hc-conn-pool; route=some-host; available=1; active=0;
blocking=0; max-allowed=50
The connection manager isn’t respecting the per-route connection settings.
Above we see that the “max-allowed” per route reported by the pool-manager is
50 for a route that specifically set the max-allowed to 200.
Any hints about what we are doing wrong to override the limit on a per-route
basis?
—
Pete Keyes