【问题标题】:Service Fabric Asp.net Core Kestrel HttpClient hangs with minimal loadService Fabric Asp.net Core Kestrel HttpClient 以最小负载挂起
【发布时间】:2017-11-27 20:58:09
【问题描述】:

我有一个准系统 Service Fabric 应用程序,它在 5 个 DS3_V2 的虚拟机规模集上托管 Asp.net Core 1.1 Web API,并将 Azure 应用程序网关作为反向代理。

API 有 10 个 HttpClient,它们通过依赖注入注入不同的 URL。 一个方法中的简单foreach循环并行调用10个Httpclient:

        var cts = new CancellationTokenSource();
        cts.CancelAfter(600);

        //Logic for asyncronously parallel calling the Call method below

        public async Task<MyResponse> Call(CancellationTokenSource cts, HttpClient client, string endpoint )
        {
            var endpoint = "finalpartOfThendpoint";
            var jsonRequest = "jsonrequest";
            try
            {
                var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
                await content.LoadIntoBufferAsync();
                if (cts.Token.IsCancellationRequested)
                {
                    return new MyResponse("Token Canceled");
                }
                var response = await client.PostAsync(endpoint, content, cts.Token);

                if (response.IsSuccessStatusCode && ((int)response.StatusCode != 204))
                {
                    //do something with response and return
                    return MyResponse("Response Ok")
                }
                return MyResponse("No response")
            }

            catch (OperationCanceledException e)
            {
                return new MyResponse("Timeout");
            }
        }

所有调用都有一个 CancellationToken。 600 毫秒后,仍然挂起的 HttpCall 被取消,并且无论如何都会发回响应。 在本地和生产中一切正常,所有端点都被调用并及时返回,很少有一个在超时之前被取消。

但是当并发连接数达到30+时,ALL调用超时无论如何,直到我减少负载。

Asp.net Core 有连接限制吗?

这就是我在自定义工厂中创建 HttpClients 以在主控制器中注入的方式:

 public static HttpClient CreateClient(string endpoint)
    {
     var client = new HttpClient
       {
          BaseAddress = new Uri(endpoint)
       };
       client.DefaultRequestHeaders.Accept.Clear();
       client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        return client;
    }

所有的 Httpclients 都被重用并且是静态的。 完全相同的代码在 Service Fabric 中的 OWIN 上托管的 Asp.net Web API 2 上完美运行。问题仅出在 Asp.net Core 1.1

看到网上创建了一个HttpClientHandler,但是没有并发连接的参数。

我可以做些什么来进一步调查? 没有抛出异常,但 OperationcanceledException 和 如果我删除 CancellationToken 调用会卡住并且 CPU 达到 100%,基本上 30 个连接会破坏 5 个四核服务器的能力。

这与从 Kestrel 发出的呼叫数量有关。


更新

我用 WebListener 试过了,问题依然存在,所以不是 Kestrel,而是 Asp.net Core

【问题讨论】:

  • 您的所有 httpclients 都使用相同的端点还是为每个客户端创建一个端点?

标签: asp.net-core asp.net-core-mvc azure-service-fabric asp.net-core-webapi kestrel-http-server


【解决方案1】:

我想通了。

Asp.net 核心仍然有一些 HttpClient 限制,用于连接到与旧的 Asp.net WebAPI 相同的服务器。 它的记录很差,但是现在必须通过 HttpClientHandler 传递 maxconnections 的旧 ServicepointManager 选项。 我只是像这样创建HttpClient,问题就消失了。

 var config = new HttpClientHandler()
            {
                MaxConnectionsPerServer = int.MaxValue
            };
            var client = new HttpClient(config)
            {
                BaseAddress = new Uri('url here')
            };

真的,如果团队中的某个人正在阅读,这应该是默认设置。

【讨论】:

    猜你喜欢
    • 2020-07-30
    • 2023-04-06
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 2018-11-17
    • 2017-02-27
    • 2018-09-15
    相关资源
    最近更新 更多