有没有办法(以及如何)知道连接池的状态?比如,正在使用多少个连接,有多少可用,......
我们目前面临的问题是应用程序无法从池中获取连接(ConnectionPoolTimeoutException:等待池中的连接超时),因此为了追踪原因,我们希望在每次请求新连接时记录一些池统计信息。
我一直在浏览 Apache HTTPClient API,但没有找到获取此信息的方法。
我们使用 PoolingClientConnectionManager。
有没有办法(以及如何)知道连接池的状态?比如,正在使用多少个连接,有多少可用,......
我们目前面临的问题是应用程序无法从池中获取连接(ConnectionPoolTimeoutException:等待池中的连接超时),因此为了追踪原因,我们希望在每次请求新连接时记录一些池统计信息。
我一直在浏览 Apache HTTPClient API,但没有找到获取此信息的方法。
我们使用 PoolingClientConnectionManager。
您可以使用ConnPoolControl接口的方法来控制内部池的参数
您可以使用以下代码获得详细信息总计和每条路线:
public static void main(String[] args) {
PoolingHttpClientConnectionManager connectionManager = HttpClientUtils.getConnectionManager();
System.out.println(createHttpInfo(connectionManager));
}
private static String createHttpInfo(PoolingHttpClientConnectionManager connectionManager) {
StringBuilder sb = new StringBuilder();
sb.append("=========================").append("\n");
sb.append("General Info:").append("\n");
sb.append("-------------------------").append("\n");
sb.append("MaxTotal: ").append(connectionManager.getMaxTotal()).append("\n");
sb.append("DefaultMaxPerRoute: ").append(connectionManager.getDefaultMaxPerRoute()).append("\n");
sb.append("ValidateAfterInactivity: ").append(connectionManager.getValidateAfterInactivity()).append("\n");
sb.append("=========================").append("\n");
PoolStats totalStats = connectionManager.getTotalStats();
sb.append(createPoolStatsInfo("Total Stats", totalStats));
Set<HttpRoute> routes = connectionManager.getRoutes();
if (routes != null) {
for (HttpRoute route : routes) {
sb.append(createRouteInfo(connectionManager, route));
}
}
return sb.toString();
}
private static String createRouteInfo(PoolingHttpClientConnectionManager connectionManager, HttpRoute route) {
PoolStats routeStats = connectionManager.getStats(route);
String info = createPoolStatsInfo(route.getTargetHost().toURI(), routeStats);
return info;
}
private static String createPoolStatsInfo(String title, PoolStats poolStats) {
StringBuilder sb = new StringBuilder();
sb.append(title + ":").append("\n");
sb.append("-------------------------").append("\n");
if (poolStats != null) {
sb.append("Available: ").append(poolStats.getAvailable()).append("\n");
sb.append("Leased: ").append(poolStats.getLeased()).append("\n");
sb.append("Max: ").append(poolStats.getMax()).append("\n");
sb.append("Pending: ").append(poolStats.getPending()).append("\n");
}
sb.append("=========================").append("\n");
return sb.toString();
}
连接管理器是从我创建的实用类中检索的(您可以以不同的方式创建它):
public class HttpClientUtils {
private static final PoolingHttpClientConnectionManager connectionManager = createConnectionManager();
private static PoolingHttpClientConnectionManager createConnectionManager() {
try {
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
SSLContext.getDefault(),
new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"},
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", socketFactory)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(20);
return cm;
} catch (NoSuchAlgorithmException | RuntimeException ex) {
Logger.getLogger(HttpClientUtils.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
public static PoolingHttpClientConnectionManager getConnectionManager() {
return connectionManager;
}
}