34

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 可以同时处理的最大请求数。这包括排队的请求和正在执行的请求。如果“Requests Current”性能计数器超过 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 服务器繁忙错误。

4

1 回答 1

4

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

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

编辑:

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

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

于 2012-06-15T00:40:19.550 回答