【问题标题】:Understanding the lifecycle of a connection managed by PoolingHttpClientConnectionManager in Apache HTTP client了解 Apache HTTP 客户端中由 PoolingHttpClientConnectionManager 管理的连接的生命周期
【发布时间】:2021-02-16 22:03:48
【问题描述】:

在阅读了 Apache HTTP 组件模块的Connection Management 文档,以及一些关于连接保持活动策略和连接驱逐策略的其他资源后,我感到非常困惑。

其中使用了一堆形容词来描述连接的状态,例如 staleidleavailableexpiredclosed 等。没有描述如何使用的生命周期图这些状态之间的联系会发生变化。

我的困惑主要来自以下情况。

我通过下面的代码 sn-p 设置了一个 ConnectionKeepAliveStrategy,它提供了 5 秒的 KeepAliveDuration

        ConnectionKeepAliveStrategy keepAliveStrategy = ( httpResponse, httpContext ) -> {
            HeaderElementIterator iterator = 
                 new BasicHeaderElementIterator( httpResponse.headerIterator( HTTP.CONN_KEEP_ALIVE ) );
            while ( iterator.hasNext() )
            {
                HeaderElement header = iterator.nextElement();
                if ( header.getValue() != null && header.getName().equalsIgnoreCase( "timeout" ) )
                {
                    return Long.parseLong( header.getValue(), 10) * 1000;
                }
            }
            return 5 * 1000;
        };
        this.client = HttpAsyncClients.custom()
                .setDefaultRequestConfig( requestConfig )
                .setMaxConnTotal( 500 )    
                .setMaxConnPerRoute( 500 )
                .setConnectionManager( this.cm )  
                .setKeepAliveStrategy( keepAliveStrategy )
                .build();

我正在与之交谈的服务器确实支持保持连接。当我在一个批处理中异步执行大约 200 个请求后打印出连接管理器的池统计信息时,观察到以下信息。

Total Stats:
-----------------
Available: 139
Leased: 0
Max: 500
Pending: 0

在等待 30 秒后(到那时,keep-alive 超时早已超过),我开始了新一批相同的 HTTP 调用。检查连接管理器池统计信息后,可用连接数仍为 139。

不应该是零,因为已经达到 keep-alive 超时? PoolStats Java doc 声明 Available 是“空闲持久连接的数量”。空闲的持久连接是否被认为是活跃的?

我认为Apache HttpClient: How to auto close connections by server's keep-alive time 很受欢迎,但希望一些专家可以对PoolingHttpClientConnectionManager 管理的连接的生命周期给出有见地的解释。

其他一些一般性问题:

  1. HttpAsyncClients.createdDefault() 中使用的默认连接管理器是否自行处理连接保持活动策略和连接驱逐?
  2. 在自定义基础上实施它们可能需要哪些要求/限制?他们会互相矛盾吗?

【问题讨论】:

    标签: java apache-httpclient-4.x keep-alive httpconnection


    【解决方案1】:

    记录我的一些进一步发现,这些发现可能部分满足作为答案。

    1. 无论是否使用ConnectionKeepAliveStrategy 设置保持活动会话的超时时间,连接最终都将处于ESTABLISHED 的TCP 状态,通过netstat -apt 进行检查。我观察到它们在我的 Linux 测试环境中大约 5 分钟后会自动回收。

    2. 当不使用ConnectionKeepAliveStrategy 时,在第二批请求时,已建立的连接将被重用。

    3. 当使用 ConnectionKeepAliveStrategy 并且未达到超时时,在第二个请求批次时,已建立的连接将被重用。

    4. 当使用ConnectionKeepAliveStrategy且超时时间已过时,在第二次请求批处理时,已建立的连接将被回收到TIME_WAIT状态,表明客户端已决定关闭连接。

    5. 可以通过在单独的连接驱逐线程中执行 connectionManager.closeExpiredConnections(); 来主动执行此回收,这会将连接引导到 TIME_WAIT 阶段。

    我认为一般的观察是ESTABLISHED连接被连接池统计信息视为Available,并且带有超时的连接保持活动策略确实使连接到期,但它仅在新请求时生效被处理,或者当我们特别指示连接管理器关闭过期连接时。

    TCP state diagram 来自维基百科供参考。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-28
      • 1970-01-01
      • 2018-01-31
      • 2020-07-07
      • 1970-01-01
      • 1970-01-01
      • 2015-02-01
      • 1970-01-01
      相关资源
      最近更新 更多