Ste*_*n C 5 c# dotnet-httpclient .net-core .net-core-3.1
我有一个 .Net Core 3.1 应用程序。在应用程序中,我使用 IHttpClientFactory 创建 HttpClient。当我使用 SendAsync 进行调用时,第一个请求需要 2 秒多的时间,而后续请求需要不到 100 毫秒。对于生产应用程序来说,这是不可接受的性能。
我还注意到,如果我一段时间没有提出任何请求,就会发生这种情况。我遇到了 PooledConnectionIdleTimeout 属性,该属性默认为 2 分钟,我可以延长该时间,但这仅适用于已存在的池连接,不适用于需要创建新连接的情况。
我在 Startup.cs 中配置 HttpClient,如下所示:
services.AddHttpClient("Default")
.ConfigurePrimaryHttpMessageHandler(() =>
{
return new SocketsHttpHandler
{
UseCookies = false,
AllowAutoRedirect = false,
MaxConnectionsPerServer = int.MaxValue,
UseProxy = false
};
});
Run Code Online (Sandbox Code Playgroud)
我有一个 Singleton 包装类,其中包含一个调用 SendAsync 的方法:
public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken = default)
{
var client = m_HttpClientFactory.CreateClient("Default");
return await client.SendAsync(request, completionOption, cancellationToken).ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)
我缺少某种配置吗?或者我可以做一些预热,这样第一个请求就不会花很长时间?
更新:已经过去几个月了,我不记得所有细节,但考虑到最近的评论,我决定发布我的发现和解决方法。
我发现当使用 IP 地址作为主机名而不是服务器名称时,不会出现此问题。就我而言,我几乎总是调用 localhost,因此我会比较我应该访问的主机名,如果它与本地系统的主机名匹配,我会将主机更改为 127.0.0.1。
IIRC,.Net Core 逻辑将尝试获取服务器名称的所有 IP,然后逐一检查每个 IP,并尝试成功连接。根据需要循环的次数,每次失败的尝试都会增加 1 秒的时间。当我在系统上启用 IPv6 时,它可能尝试的 IP 数量会增加一倍。
希望有帮助,如果听起来含糊,抱歉。有一阵子了 :)
此处使用 SocketsHttpHandler 和 HttpClient 的另一个工作解决方案:/sf/answers/4933301901/
它在连接时使用 IPv4 over IPv6(这就是为什么它有时很慢,比如〜2s)
它为我完成了工作
| 归档时间: |
|
| 查看次数: |
2276 次 |
| 最近记录: |