HttpClient的PooledConnectionLifetime对现有连接的影响及请求中断疑问
我们使用HttpClient发起请求时,将PooledConnectionLifetime设置为5秒,示例代码如下:
// C# 示例代码 var socketsHandler = new SocketsHttpHandler { PooledConnectionLifetime = TimeSpan.FromSeconds(5) // 仅作演示用途 }; public static HttpClient client = new HttpClient(socketsHandler); // 使用单例静态HttpClient // 服务器响应缓慢,请求耗时3秒完成 client.GetAsync("https://www.slowwebsite.com"); // 创建TCP连接并放入连接池 // 3秒后发起第二个请求 client.GetAsync("https://www.slowwebsite.com"); // 复用已有的TCP连接
第一个请求完成后,TCP连接被存入连接池,第二个请求会复用该连接。但到第5秒时,该TCP连接应因PooledConnectionLifetime的设置被关闭。
我的问题
- 该TCP连接会立即关闭并进入TIME_WAIT状态吗?如果立即关闭,正在进行的第二个请求会不会被中断?
- 如果该连接不会立即关闭,而是等待第二个请求完成后再关闭,这是否与
IHttpClientFactory的行为一致?
IHttpClientFactory示例代码
builder.Services.AddHttpClient("typicode", c => { c.BaseAddress = new Uri("https://www.slowwebsite.com/"); }) .SetHandlerLifetime(TimeSpan.FromSeconds(5));
相关描述(翻译)
若TCP连接在
PooledConnectionLifetime设置的时间到期后立即关闭,那么处理器过期并不会立即释放TCP连接。过期的处理器(由SetHandlerLifetime控制)会被放入一个单独的池,只有当这些处理器不再被引用时,才会被定期处理并释放。
核心解答
单例HttpClient的连接处理逻辑
当PooledConnectionLifetime到期时,不会立即关闭正在被使用的TCP连接。SocketsHttpHandler会标记该连接为到期状态,不再将其分配给新的请求,但已在使用的连接会正常完成当前请求流程,待请求结束后才会被关闭并进入TIME_WAIT状态,因此正在进行的第二个请求不会被中断。与IHttpClientFactory的行为一致性
SetHandlerLifetime控制的是HttpMessageHandler实例的生命周期,而非单个TCP连接的生命周期。当处理器到期后,它不会被立即销毁,而是被移至单独的池中,等待所有依赖该处理器的请求完成(即处理器不再被引用)后,才会被定期清理。这和直接设置PooledConnectionLifetime的核心逻辑一致——都不会中断正在进行的请求,只是管控的对象层级不同:前者针对处理器实例,后者针对单个TCP连接。
你引用的描述实际是说明处理器不会被立即销毁,而非TCP连接会中断请求。无论使用单例HttpClient还是IHttpClientFactory,正在执行的请求都不会因生命周期设置到期而被中断。
内容的提问来源于stack exchange,提问作者user22155685

