ASP.NET如何确定是否将请求排队?

问题描述

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

解决方法

我一直在做研究,我相信我已经得出了可以接受的答案。我的主要来源是这篇文章: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限制,但该限制确实很高。 如果您长时间进行网络呼叫的同步处理和阻止,则很有可能遇到这些限制。在.NET 4之前需要注意MaxConcurrentRequestsPerCPU,但仍然有ThreadPool。 性能测试 我进行了一个简单的测试,以了解这种限制是如何工作的。我有一个简单的页面,调用了500毫秒的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在处理负载方面做得更好。 异步仍然是最好的。     ,IIS在开始对请求进行排队之前不会使用所有可用线程,因为如果正在执行的请求需要其他线程,则这些线程需要保持可用状态。 IIS经过优化,可以优先考虑执行请求,并且它不希望执行请求被阻塞,因为工作进程耗尽了可用线程。 默认最大线程池20,最小空闲线程池为8,这意味着在将新请求排队之前,系统将仅执行12个请求。 “最大线程数”乘以“核心数”,但不是“最小线程数”,因此默认情况下,双线程盒在排队之前将允许32个请求。 至于剩余的CPU,ASP.NET不会对其进行监视。它仅与正在使用的线程数有关。这些线程可能被磁盘访问,传输数据库结果的网络访问或仅是Thread.Sleep阻止,即使CPU没有达到最大值,这些线程仍然会导致新请求进入队列。 有关性能的信息,请参见《 MS模式和实践》一书。它适用于IIS6 / .NET 1.1,但概念仍然存在。 http://msdn.microsoft.com/zh-CN/library/ff647787.aspx#scalenetchapt06_topic8 重新配置IIS7 / .NET 2+:http://msdn.microsoft.com/zh-cn/library/e1f13641.aspx