ASP.NET请求排队和上下文切换次数过高

4
我们有一个相当受欢迎的网站,每个月约有400万用户。它托管在具有16 GB RAM、2个处理器和24个核心的专用服务器上。
在任何时候,CPU始终低于40%,内存低于12 GB,但在最高流量期间,性能非常差。网站非常非常慢。我们有两个应用程序池,一个用于我们的主站点,一个用于我们的论坛。只有网站速度很慢。我们没有对每个应用程序池的CPU或内存设置任何限制。
我查看了性能计数器,并发现了一些非常有趣的事情。在我们的高峰时间,请求被排队等待。总体上,上下文切换数字非常高,约为30-110000 k。
据我所知,高上下文切换是由锁引起的。有人可以给我提供一个会导致上下文切换数量很高的示例代码吗?

有没有人有什么建议或者任何代码示例可以导致高上下文切换?由于我们通过http处理程序提供了大量的小文件,这可能会导致问题。所有文件都存储在一个文件夹中,该文件夹中大约有200,000个文件。 - nristic
根据许多文章的建议,我也监视了性能计数器.NET CLR LocksAndThreads(w3wp)\Contention Rate / sec和.NET CLR LocksAndThreads(w3wp)\Current Queue Length,以验证是否存在锁定问题导致上下文切换次数过高。但是,这两个性能计数器始终都显示为0。请问有什么建议或帮助? - nristic
同步IO是阻塞的,这意味着它会卡住工作进程并导致请求在工作进程完成之前排队。我怀疑处理程序正在同步读取这些小文件。 - stuisme
1个回答

2
我不太关心上下文切换,也不认为数字很大。您在IIS中运行了很多线程(因为它是一台24核机器),因此预计上下文切换数字会更高。但是,我确实关心请求排队。
我会做几件事情,并观察它们如何影响您的性能计数器:
您的服务器CPU明显未被充分利用,因为它一直保持在40%以下。您可以尝试在IIS中将“每个处理器限制的线程数”设置为更高的值,直到达到50-60%的利用率。按照书本上的最佳实践,每个核心的线程数应该是20,但这取决于具体情况,您可以尝试使用更高或更低的值。我建议尝试将值设置为>=30。低CPU利用率也可能是阻塞IO操作的迹象。
调整IIS属性中的“队列长度”设置。如果您已将“每个处理器限制的线程数”配置为20,则应将队列长度配置为20 x 24个核心=480。同样,如果请求正在排队,这可能意味着所有线程都被阻止为其他请求提供服务或等待IO响应。
不要从IIS中提供静态文件。将它们移到CDN、Amazon S3或其他地方。这将显著提高服务器性能,因为数千个服务器请求将去往其他地方!如果必须从IIS中提供文件,则配置IIS文件压缩。此外,对于静态内容,请使用过期标头,以便它们在客户端上缓存,这将节省大量带宽。
在您的ASP.NET控制器、处理程序等中尽可能使用异步IO(从磁盘、数据库、网络等读取/写入),以确保您的线程得到最佳利用。在重载下阻塞可用线程使用阻塞IO(在我见过的95%的ASP.NET应用程序中都是如此)可能会导致线程池在重负载下被充分利用,从而导致排队。
进行一般优化,以防止请求命中您的服务器的数量和单个请求的处理时间。这可以包括对CSS / JS文件进行缩小和捆绑,重构JavaScript以减少与服务器的往返次数,重构控制器/处理程序方法以使其更快等等。我在下面添加了Google和Yahoo建议的链接。
在IIS中禁用ASP.NET调试。
谷歌和雅虎的推荐:

https://developers.google.com/speed/docs/insights/rules

https://developer.yahoo.com/performance/rules.html

如果你遵循所有这些建议,我相信你会得到一些改善!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接