Kestrel在高负载下达到100%cpu,即使负载在减少,也会保持这种状态

时间:2017-06-10 15:48:03

标签: c# asp.net-core kestrel-http-server

我面临着非常困难的局面。我将生产网站从asp.net 4.5迁移到asp.net核心1.1。 asp.net 4.5中的站点托管在IIS 8.5,3个服务器4核/ 7Gb RAM上,每天流量为2百万用户。一切都很好。

现在,当我运行带有核心的网站,使用Debian 8托管,nginx作为反向代理和Kestrel时,我经常看到该服务在许多情况下达到100%。 由于网站上有许多控制器,因此很难缩小到一个问题。但我想我已经成功地重现了一种情况。

该方案是基于发送到站点的异步控制器的参数生成多个映像。这些参数让我生成一个html,这个html被发送到另一个外部服务,而这个服务用phantomjs生成图像。 大多数情况下,生成的图像必须分成多个部分,以便它们可以集成到html页面中以便可点击。

例如,我们有一个具有这种html的网页:

<table>
<tr>
    <td><img src="http://www.my-web-site.com/images/GetImages?index=0&...."></td>
    <td><img src="http://www.my-web-site.com/images/GetImages?index=1&...."></td>
</tr>
</table>

以下是步骤: - 调用异步GetImage

如果index = 0 - 生成Html - 使用异步HttpClient(仅一个静态实例)将HTML发送到HtmlToImageServer - 等待映像索引0准备就绪,通过await Task.Delay(500)每隔500毫秒检查一次数据库(最多可能需要2或3秒) - 准备好后重定向到图像网址

如果索引&gt; 0 - 等待await Task.Delay(500)准备好图像索引n - 准备好后重定向到图像网址

该方案有效,这是肯定的。但正如我所说,cpu有时会达到100%并且不再提供任何请求。服务器没有响应,我所能做的就是杀死进程。 完全相同的方案适用于带有IIS的asp.net 4.5。

我认为我的服务器调整正常,nginx配置正确(我尝试在单独的服务器上使用nginx)。我还试过更强大的服务器 - &gt; 8核/ 14Gb内存,完全相同。

我希望我的情景很明确。我不知道这是否是来自Kestrel的错误。我唯一能想到的是我使用async / await存在问题,并且某处会出现死锁,但在我看来,如果是这样的话,这根本不会起作用吗? 我试图在Windows下运行该服务以便能够对其进行分析。我认为我解决了很多问题。但它还没有奏效。 我应该寻找什么?

如果我能澄清任何一点,请告诉我,非常感谢你的帮助。我已经在这个问题上工作了一个月了,而且我的想法不合时宜。

编辑: 我终于找到了一些解决方案/解决方法。

首先,我通过将ThreadPool的最小线程设置为过高的值(32675)而犯了一个错误。通过从Windows .net 4.5站点获取此值,可以找到此值。 当我将此值设置为min 200 / max 200 / completion 200时,网站似乎以更好的方式处理请求。

但另一件事是我配置Nginx来处理每个核心80000个请求。这里的问题似乎是,如果nginx发送了太多请求,那么kestrel会继续接受新的请求而且它会因为等待http客户端请求回答而不堪重负,

所以现在,我配置Nginx来处理512个只有1个核心的请求。它似乎没问题,但是当有一个尖峰时,nginx抱怨没有足够的工人连接。如果我尝试设置1024而不是512,则cpu会非常快地达到100%。

奇怪的是,iis + asp.net 4.5并没有发生这种情况。我在这里找不到任何东西?

0 个答案:

没有答案