假设我们使用 HttpClient 发出请求并将
PooledConnectionLifetime
设置为 5 秒
// C# pseudo code, not in the right format
var socketsHandler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromSeconds(5) // just for demo purpose
};
public static client = new HttpClient(socketsHandler); // we use a single static `HttpClient`
// takes 3 seconds to finish a request as the server is slow
client.GetAsync("https://www.slowwebsite.com"); // create a TCP connection and put this connection in a pool
// after 3 seconds , send another request
client.GetAsync("https://www.slowwebsite.com"); // re-use the TCP connection
因此,在第一个请求之后,将建立并池化 TCP 连接,当我们发出第二个请求时,它可以重新使用 TCP 连接。
但是在第 5 秒,由于 PooledConnectionLifetime 设置为 5 秒,tcp 连接应该关闭。
我的问题是,tcp连接会立即关闭(变成TIME_WAIT状态)吗?如果立即关闭,那第二个请求不就被打断停止了吗?
如果tcp连接不会立即关闭,而是先等待第二个请求完成再关闭连接,这不是IHttpClientFactory所做的吗:
builder.Services.AddHttpClient("typicode", c =>
{
c.BaseAddress = new Uri("https://www.slowwebsite.com/");
})
.SetHandlerLifetime(TimeSpan.FromSeconds(5));
但根据本文,场景 5:使用 IHttpClientFactory https://www.mytechramblings.com/posts/dotnet-httpclient-basic-usage-scenarios/#:~:text=Once%20this%20lifetime%20expires%2C %20the,并且%20从%20the%20池中删除了%20。
TCP 连接在 PooledConnectionLifetime 属性设置的时间到期后立即关闭,到期的处理程序不会立即处置 TCP 连接。过期的处理程序(由 SetHandlerLifetime 控制)将被放置在一个不同的池中,该池会定期进行处理,以仅在处理程序变得无法访问时才将其处置。
听起来就像在我的
HttpClient
示例中,第二个请求将被中断并停止?
需要使用PooledConnectionIdleTimeout来确保TCP关闭
private static readonly HttpClient Client = new(new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(30),
PooledConnectionIdleTimeout = TimeSpan.FromSeconds(10)
})
PooledConnectionLifetime 设置为 30 分钟,这意味着 TCP 连接将在 30 分钟内被重用。 PooledConnectionIdleTimeout 设置为 10 秒,这意味着空闲 TCP 连接最多将在 10 秒后关闭,无论是否达到 PooledConnectionLifetime 时间。
来源:https://www.mytechramblings.com/posts/dotnet-httpclient-basic-usage-scenarios/