检查PoolingClientConnectionManager中的可用连接

时间:2013-10-01 09:06:26

标签: httpclient apache-httpclient-4.x

有没有办法(以及如何)知道连接池的状态?比如,正在使用多少个连接,有多少可用,......

我们目前面临的问题是应用程序无法从池中获取连接(ConnectionPoolTimeoutException:Timeout等待来自池的连接),因此要在每次请求新连接时跟踪我们想要记录某些池统计信息的原因。

我一直在浏览Apache HTTPClient API,但没有找到获取此信息的方法。

我们使用PoolingClientConnectionManager。

2 个答案:

答案 0 :(得分:2)

您可以使用ConnPoolControl接口的方法来控制内部池的参数

答案 1 :(得分:2)

您可以使用以下代码获得详细信息总数和每条路线:

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();
}

更新(2019-01-07)

连接管理器是从我创建的功利类中检索的(你可以用不同的方式创建它):

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;
    }
}