如何阻止出站 HTTP 连接超时

Dan*_*nds 5 azure kestrel docker flurl asp.net-core

背景:

我目前在 Azure 中托管一个具有以下规格的 ASP.NET 应用程序:

  • ASP .Net 核心 2.2
  • 使用 Flul 进行 HTTP 请求
  • Kestrel 网络服务器
  • Docker(Linux - mcr.microsoft.com/dotnet/core/aspnet:2.2 运行时)
  • P2V2 层应用服务计划上的 Azure 应用服务

我有几个在服务上运行的后台作业,这些作业对第三方服务进行大量出站 HTTP 调用。

问题:

在小负载(大约每 10 秒 1 次调用)下,所有请求都在一秒钟内完成,没有任何问题。我遇到的问题是,在重负载下,当服务可以在 10 秒内进行多达 3/4 次调用时,某些请求将随机超时并引发异常。当我使用 RestSharp 时,异常会显示“操作已超时”。现在我正在使用 Flurl,异常显示为“调用超时”。

关键在于 - 如果我从运行 Windows 10 / Visual Studios 2017 的笔记本电脑运行相同的作业,则不会出现此问题。这让我相信我在托管环境中遇到了某些限制或耗尽了某些资源。不清楚这是否与连接/套接字或线程相关。

我尝试过的事情:

  • 确保请求的所有代码路径都用于async/await防止锁定
  • 确保 Kestrel 默认允许无限连接(默认情况下)
  • 确保 Docker 默认连接限制足够(默认 2000 个,绰绰有余)
  • 配置ServicePointManager连接限制设置

这是我的startup.cs中的代码,我目前正在使用它来尝试防止此问题:

public class Startup
{
    public Startup(IHostingEnvironment hostingEnvironment)
    {
        ...

        // ServicePointManager setup
        ServicePointManager.UseNagleAlgorithm = false;
        ServicePointManager.Expect100Continue = false;
        ServicePointManager.DefaultConnectionLimit = int.MaxValue;
        ServicePointManager.EnableDnsRoundRobin = true;
        ServicePointManager.ReusePort = true;

        // Set Service point timeouts
        var sp = ServicePointManager.FindServicePoint(new Uri("https://placeholder.thirdparty.com"));
        sp.ConnectionLeaseTimeout = 15 * 1000; // 15 seconds  

        FlurlHttp.ConfigureClient("https://placeholder.thirdparty.com", cli => cli.Settings.ConnectionLeaseTimeout = new TimeSpan(0, 0, 15));
    }
}
Run Code Online (Sandbox Code Playgroud)

还有其他人遇到过类似的问题吗?我愿意接受有关如何最好地调试这种情况的任何建议,或者纠正问题的可能方法。研究了几天后我完全不知所措。

先感谢您。

Ahm*_*met 3

我有类似的问题。看一下Asp.net Core HttpClient 有很多 TIME_WAIT 或 CLOSE_WAIT 连接。通过调试netstat帮助我确定了问题。作为一种可能的解决方案。我建议你使用IHttpClientFactory. 您可以从https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2获取更多信息它应该相当容易使用,如ASP 中的 Flurl 客户端生命周期中所述.Net Core 2.1 和 IHttpClientFactory