ASP.NET如何确定是否对请求进行排队?

时间:2011-05-25 17:42:21

标签: asp.net threadpool

当ASP.NET收到请求时,它如何确定是为其提供服务还是对其进行排队?我问,因为我正在监视服务器上的性能计数器并且CPU没有超出并且有大量可用的工作线程,但我仍然看到最多200个请求排队。

2 个答案:

答案 0 :(得分:15)

我一直在做研究,我相信我已经得到了一个可以接受的答案。我的主要来源是这篇文章:http://blogs.msdn.com/b/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx

据我所知,请求处理有两种主要方式受到限制。第一个是MaxConcurrentRequestsPerCPU属性。在.NET 4之前,默认设置为12。在.NET 4中,它被更改为5000.对于异步请求,他们希望允许很多,而对于同步请求,他们认为ASP.NET ThreadPool会很好地限制同步请求。第二个当然是ThreadPool本身。在ASP.NET发布请求后,它可以决定何时发布。

如果您正在进行异步处理,那么您的限制因素可能是CPU,网络和磁盘,而不是任何ASP.NET请求限制。它可能会达到MaxConcurrentRequestsPerCPU限制,但是这个限制真的很高。

如果您长时间在网络电话上进行同步处理和屏蔽,则更有可能遇到这些限制。 MaxConcurrentRequestsPerCPU在.NET 4之前需要注意,但仍然存在ThreadPool。

性能测试
我整理了一个简单的测试,看看这种节流是如何起作用的。我有一个500ms Thread.Sleep()调用的简单页面。一台主机同时发出800个异步请求,一台运行ASP.NET的工作机器处理它们。结果很有意思:

.NET 3.5,无修改:46秒。使用进程资源管理器看到9个工作线程 .NET 3.5,MaxConcurrentRequestsPerCPU设置为5000:46秒。 9个工作线程。
.NET 4:42秒,或者在热运行时为13秒。看到大约35个工人线程逐渐被创造出来 .NET 4,异步:3秒

一些观察结果:

  • MaxConcurrentRequestsPerCPU没有被击中。看起来这是ThreadPool本身的限制。
  • .NET 3.5似乎不太愿意创建新线程来处理同步请求。 .NET 4可以更好地处理负载。
  • 异步仍然是一个国家里程最好的。

答案 1 :(得分:2)

IIS在开始排队请求之前不会使用所有可用线程,因为如果执行请求需要其他线程,这些线程需要保持可用。 IIS经过优化,优先执行请求,并且不希望执行请求被阻止,因为工作进程耗尽了可用的线程。

默认最大线程池20,最小值为8,这意味着系统只会在新请求排队之前执行12个请求。最大线程数乘以核心数,但最小线程数不是,因此默认情况下,在核心排队之前,它将允许32个请求。

至于剩余的CPU,ASP.NET不会监视它。它纯粹是关于使用的线程数。这些线程可能被磁盘访问,网络访问传输数据库结果或简单的Thread.Sleep阻塞,即使CPU没有达到最大值,这仍然会导致新请求进入队列。

更多信息可在MS Patterns&关于绩效的实践书。它适用于IIS6 / .NET 1.1,但概念仍然存在。 http://msdn.microsoft.com/en-us/library/ff647787.aspx#scalenetchapt06_topic8

重新配置IIS7 / .NET 2+:http://msdn.microsoft.com/en-us/library/e1f13641.aspx