ASP.NET IIS - 请求何时排队?

nmd*_*mdr 32 asp.net iis multithreading iis-6

Thomas Marquardt撰写的以下文章描述了IIS如何处理ASP.Net请求,可配置为运行的最大/最小CLR工作线程/托管IO线程,涉及的各种请求队列及其默认大小.

现在根据文章,IIS 6.0中发生以下情况:

  1. ASP.NET从IIS IO线程中获取请求,并将"HSE_STATUS_PENDING"发布到IIS IO线程
  2. 请求被移交给CLR Worker线程
  3. 如果请求具有高延迟并且所有线程都被占用(线程计数接近httpRuntime.minFreeThreads),则请求将发布到应用程序级别请求队列(此队列是每个AppDomain)
  4. ASP.NET还会检查并发执行请求的数量.文章指出"如果并发执行请求的数量太高",它会将传入的请求排队到ASP.NET全局请求队列(这是每个工作进程)(请检查更新2)

我想知道什么是"阈值",此时ASP.NET认为当前执行它的请求数太高,然后开始将请求排队到全局ASP.NET请求队列?

我认为这个阈值将取决于最大工作线程数的配置,但可能有一些公式基于哪个ASP.NET将确定并发执行请求的数量太高并开始将请求排队到ASP.NET全局请求队列.这个公式可能是什么?或者此设置是否可配置?


更新
我再次阅读文章,在评论部分我发现了这个:

1)在IIS 6和IIS 7经典模式下,每个应用程序(AppDomain)都有一个队列,用于维护工作线程的可用性.如果可用工作线程数低于httpRuntime minFreeThreads指定的限制,则此队列中的请求数会增加.当超过httpRuntime appRequestQueueLimit指定的限制时,请求将被拒绝,并显示503状态代码,并且客户端收到带有"服务器太忙"消息的HttpException.还有一个ASP.NET性能计数器"应用程序队列中的请求",指示队列中有多少请求.是的,CLR线程池是.NET ThreadPool类公开的线程池.

2)requestQueueLimit命名不佳.它实际上限制了ASP.NET可以同时处理的最大请求数.这包括排队的请求和正在执行的请求.如果"请求当前"性能计数器超过requestQueueLimit,则将使用503状态代码拒绝新的传入请求.

因此,基本上requestQueueLimit限制了排队的请求数(我假设它将在应用程序队列中排队的请求数加上全局ASP.Net请求队列加上当前正在执行的请求数)并正在执行.虽然这不能回答原始问题,但它确实提供了有关何时因为大量并发请求/高延迟请求而可能收到503服务器忙碌错误的信息. (检查更新2)


更新2 我的理解中存在错误.我混淆了IIS 6和IIS 7的描述.
实际上,当ASP.NET以集成模式托管在IIS 7.5和7.0上时,应用程序级队列不再存在,ASP.NET维护一个全局请求队列.
因此,如果认为执行请求的数量很高,IIS 7/7.5将开始将请求排队到全局请求队列.这个问题更适用于IIS 7/7.5而不是6.

IIS 6.0而言,没有全局ASP.NET请求队列,但以下情况属实:
1.ASP.NET从IIS IO线程中获取请求并将"HSE_STATUS_PENDING"发布到IIS IO线程
2.请求被移交给CLR工作线程
3.如果请求具有高延迟并且所有线程都被占用(线程计数接近httpRuntime.minFreeThreads),那么请求是发布到应用程序级别请求队列(此队列是每个AppDomain)
4.此外,ASP.NET还会在接受新请求之前检查排队和当前正在执行的请求数.如果此数字大于processModel.requestQueueLimit指定的值,则将拒绝传入的请求,并显示503服务器繁忙错误.

ult*_*ife 4

本文可能有助于更好地理解这些设置。

minFreeThreads:如果线程池中的可用线程数低于此设置的值,工作进程将使用此设置对所有传入请求进行排队。此设置有效地将可以并发运行的请求数量限制为 maxWorkerThreads minFreeThreads。将 minFreeThreads 设置为 88 * CPU 数。这将并发请求数限制为 12 个(假设 maxWorkerThreads 为 100)。

编辑:

在这篇SO 文章中,Thomas 提供了集成管道中请求处理的更多细节和示例。请务必阅读答案的评论以获取更多解释。

本机回调(在 webengine.dll 中)在 CLR 工作线程上获取请求,我们将maxConcurrentRequestsPerCPU * CPUCount与活动请求总数进行比较。如果超出限制,请求将插入全局队列(本机代码)。否则将被执行。如果已排队,则当其中一个活动请求完成时,它将出队。