1

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

我们目前面临的问题是应用程序无法从池中获取连接(ConnectionPoolTimeoutException:等待池中的连接超时),因此为了追踪原因,我们希望在每次请求新连接时记录一些池统计信息。

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

我们使用 PoolingClientConnectionManager。

4

2 回答 2

3

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

于 2013-10-02T08:18:58.330 回答
3

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

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;
    }
}
于 2017-06-09T20:12:02.020 回答