【问题标题】:Get stats of reused connections with PoolingHttpClientConnectionManager使用 PoolingHttpClientConnectionManager 获取重用连接的统计信息
【发布时间】:2021-04-07 21:29:46
【问题描述】:

如何从 PoolingHttpClientConnectionManager 获取重用连接数

它包含返回 PoolStats 的 getTotalStats() 方法,但不存在有关重用连接数量的信息。

PoolingHttpClientConnectionManager 有一个 CPool 的私有实例,它从 httpcomponents-core 扩展了 AbstractConnPool。当重用连接时,getPoolEntryBlocking 方法会调用可用于此目的的 onReuse(entry) 方法。

我看不到获取此信息用于监控目的的方法。 有人看到另一种选择吗?

【问题讨论】:

    标签: java connection-pooling apache-httpclient-4.x apache-httpcomponents


    【解决方案1】:

    如果您扩展或修饰标准池连接管理器,它应该为您提供一个入口点,用于收集所需的连接重用详细信息

    public class MyPoolingHttpClientConnectionManager extends PoolingHttpClientConnectionManager {
    
        final AtomicLong reusedCount = new AtomicLong();
    
        @Override
        protected HttpClientConnection leaseConnection(
                Future<CPoolEntry> future,
                long timeout,
                TimeUnit timeUnit) throws InterruptedException, ExecutionException, ConnectionPoolTimeoutException {
            HttpClientConnection conn = super.leaseConnection(future, timeout, timeUnit);
            if (conn.isOpen()) {
                reusedCount.incrementAndGet();
            }
            return conn;
        }
    
    }
    

    【讨论】:

    • 谢谢,@ok2c,但我需要澄清一下。我看到 AbstractConnPool#getPoolEntryBlocking 方法可以使用 ConnFactory 创建一个新连接。 DefaultBHttpClientConnection#createConnection 调用 bind 方法,该方法表示调用后连接将被视为打开。似乎新连接也将具有打开状态,我可能会计算新连接,就好像它们已使用您的 sn-p 重用一样。
    • @EduardoSilva 新创建的连接未绑定到套接字,因此被视为断开连接(未打开)。
    • CPoolEntry 不是公开的。这阻止我重写该方法。
    • @EduardoSilva 我看不出为什么需要重写 CPoolEntry 中的方法只是为了收集连接重用统计信息。
    【解决方案2】:

    解决方案是继承 ConnectionRequest 并重写 get 方法,将执行委托给构造函数接收的 ConnectionRequest 实例。 p>

    然后我覆盖 PoolingHttpClientConnectionManager 中的 requestConnection 并将返回的 ConnectionRequest 与创建的子类一起包装。

    如果连接打开,我会增加重用连接的统计信息。否则,我会增加已创建连接的统计信息。

    public class MonitoredPoolingHttpClientConnectionManager extends PoolingHttpClientConnectionManager
    
        private final AtomicInteger createdConnections = new AtomicInteger();
        private final AtomicInteger reusedConnections = new AtomicInteger();
    
        @Override
        public ConnectionRequest requestConnection(HttpRoute route, Object state) {
            ConnectionRequest requestConnection = super.requestConnection(route, state);
            return new MonitoredConnectionRequest(requestConnection);
        }
        
        private class MonitoredConnectionRequest implements ConnectionRequest {
    
            private ConnectionRequest wrapped;
    
            public MonitoredConnectionRequest(ConnectionRequest requestConnection) {
                this.wrapped = requestConnection;
            }
    
            @Override
            public boolean cancel() {
                return wrapped.cancel();
            }
    
            @Override
            public HttpClientConnection get(long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, ConnectionPoolTimeoutException {
                HttpClientConnection conn = wrapped.get(timeout, timeUnit);
                if (conn.isOpen()) {
                    reusedConnections.incrementAndGet();
                } else {
                    createdConnections.incrementAndGet();
                }
                return conn;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多