asp.net-core - kestrel 中自托管的信号器中的最大并发请求数

标签 asp.net-core signalr owin

我开发的应用程序遇到了一个奇怪的问题。该应用程序是一个 Windows 服务,托管在 Kestrel 上运行的 AspNetCore 2.0。该应用程序通过充当代理的 IIS 站点接收请求。

在此应用程序中,我还使用通过 Microsoft.AspNetCore.Owin 集成的信号 2.2.2。一切都运行良好,直到我发现应用程序没有响应请求。

同一台计算机上并使用同一 IIS 服务器作为代理的其他应用程序运行良好。重新启动为站点提供服务的应用程序池暂时解决了问题。

问题再次出现,通过监控信息挖掘,当同一台计算机上有 400 个信号器 SSE 连接时,应用程序似乎挂起。这似乎是合理的,因为我发现默认情况下 OWIN 将并发请求数限制在 100 * number of cpus 。 (请注意,同一台计算机上的站点每分钟可以毫不费力地处理 5000 个请求,但这些请求不像 SignalR 那样是长期请求)

问题是,在 AspNetCore 中托管 Owin 时,我似乎找不到相同的选项。有人知道这是否可以作为解决方案以及正确的设置是什么?

编辑:我相当确定该问题是由同时打开的 SignalR 连接数量引起的,因为通过在 Javascript 中禁用它,问题就消失了。

第二次编辑:signalr似乎不是cuplrit,因为在测试和生产中都使用曲柄对站点进行负载测试,直到5000个并发连接(这是默认的IIS限制,对我来说没问题)

最佳答案

经过一番尝试和错误后,我已经能够识别并纠正问题,但这不是一件容易的事,因此如果其他人偶然发现同样的问题,我将留下这个答案。

禁用 SignalR 并不能解决问题,但会减少该问题的出现频率。

由于服务器和 IIS 上的监控,我发现当站点的连接数开始快速增长时,问题就出现了。该系统主要向其他服务发出请求,因此它没有数据库,也没有昂贵的计算。

检查代码我发现存在三个问题:

  • 为每个请求创建一个新的 HttpClient,这可能会耗尽请求之间未重用的套接字 blog blog2 blog3
  • 默认情况下,httpClient 上到单个域的最大并发连接数,此限制默认设置为 2 (!!!) blog4
  • 代码同步等待对另一个系统的每个 Web 请求(该程序是从从未显示此问题的 mvc4 站点移植的)。这在 MVC 中工作得很好,但 ASP.NET Core 对此非常敏感,因为它将快速耗尽所有可用线程,并且因为线程池以核心数量开始,它们将很快耗尽,从而使所有请求等待。可以通过 ThreadPool.SetMaxThreads(Int32, Int32) 增加此值作为临时解决方案,但唯一的解决方案是转换异步调用中的所有调用。

一旦所有调用都是异步的,问题就不会再出现。基本上,这个问题是由于线程池饥饿和 aspnet 核心对它与 MVC 的敏感性造成的。 Here您可以使用 PerfView 找到很好的解释和检测方法。

关于asp.net-core - kestrel 中自托管的信号器中的最大并发请求数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49694493/

相关文章:

docker - SignalR 应用程序在 docker 容器中部署时无法正常工作

.net-core - .NET Core SignalR,服务器超时/重新连接问题

asp.net - OWIN token 身份验证 400 来自浏览器的 OPTIONS 的错误请求

redirect - ASP.NET Core 授权重定向到错误的 URL

asp.net-core - 如何从 ASP.Net Core 5 (Razor) 中的中间件获取页面模型的类型?

c# - HubConnection.Start 仅在从单例对象调用时抛出错误

azure - Swagger 无法在以 OWIN 身份运行的 Azure Web 应用程序上运行

asp.net - 使用 Asp.Net Owin Oauth 进行增量 Google OAuth

.net - WPF 桌面应用程序中的 gRPC 服务器?

c# - ASP.NET Core 托管在 Windows 服务中 - 未提供静态文件(即/wwwroot 的内容)