【问题标题】:How to limit incoming http requests within IIS?如何限制 IIS 中传入的 http 请求?
【发布时间】:2021-11-27 23:48:20
【问题描述】:

简介

我们有一个 ASP.NET v4.6.1 Web 应用程序以集成模式托管在 IIS v10.0 (或用于开发目的的 IIS Express) - CLR ASP.NET v4.0.30319。 Web 应用程序正在处理的 Http 请求资源相对较多 - 对内部服务进行了几次调用,并对结果进行了一些处理。其中一些可能需要几秒钟。为避免物理资源耗尽,如果达到信号量容量,我们将阻止单个 http 请求(我们允许 N 个并发请求,其中 N 是有限数)。此信号量是在下游。

尽管如此,在处理新传入的请求方面没有阻塞(尽管信号量已完全填充)。 这样的请求仍然在 ASP.NET 工作程序中处理。此外,这样的处理会占用一些资源和内存空间。在请求进入引入信号量的下游之前,它需要一些处理 - 创建新对象,将参数绑定到模型中,使用动作过滤器进行一些逻辑等等。

以这种方式阻塞并不是很有效。所以我们想到,如果请求可以在 IIS 本身级别被阻止(排队),那将是理想的。因此,如果没有空闲线程来处理传入的 HTTP 请求,则该请求将被添加到 IIS 上的队列中,并且在线程空闲并准备好处理另一个请求之前,它不会转发到 ASP.NET 工作线程。

我发现它可以帮助我们在 aspnet.config 中设置一个参数,尤其是每个 CPU 的当前请求数。

由于我们主要使用 IIS Express 进行开发,我们将 aspnet.config 设置在以下路径:

%userprofile%\Documents\IISExpress\config\aspnet.config

<system.web> 
   <applicationPool maxConcurrentRequestsPerCPU="8 maxConcurrentThreadsPerCPU="0" requestQueueLimit="5000"/> 
</system.web>  

很遗憾,这些更改的设置没有生效。我还尝试更改这些路径上的 machine.config:

  • C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config
  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config

感谢性能监控工具,我一直在监控 ASP.NET v4.0.30319 Requests Queued, Requests Current 指标。 我什至在应用程序级别都没有发现任何变化。

我们想将最大并行请求设置为 96。由于我们有 6 个带超线程的内核(所以我们总共有 12 个逻辑内核)我们将 maxConcurrentRequestsPerCPU 设置为 8。

请注意:
我注意到还有另一个参数可以限制可用的并发连接。但是,这不是我们想要使用的情况,因为通过减少我们会限制其他客户端,他们可以获得 503 http 状态错误代码。

如何正确设置 IIS 以在内部队列中对请求进行排队,而不是在线程空闲之前继续处理 ASP.NET 工作线程?这甚至可能吗?

如果 IIS 无法做到这一点,是否有任何机制如何在进入 ASP.NET 工作者之前阻止和排队本机传入的请求?

【问题讨论】:

  • @LexLi 谢谢你的链接。我知道这些设置,我尝试了很多,但 IIS 不接受它们作为自己的设置。它们真的按预期工作吗?我在某处读到,例如,MinFreeThreads 对于在集成模式下使用 IIS 无效。也许我会给它最后一次机会。
  • 据我所知,在iis中只有Request Limits限制http请求,但这似乎不能满足你的需求,所以我认为在iis中是不可能的。

标签: asp.net iis iis-express iis-10


【解决方案1】:

您可以尝试使用这些选项 -

Queue Length 属性:此属性将排队等待应用程序池可以处理的最大请求 http 请求数。

https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.administration.applicationpool.queuelength?view=iis-dotnet

如果您有兴趣限制 CPU 利用率,您可以使用 CPU 下的 Limit(percent) 选项。

关于你的调用处理,看看你是否可以尝试在你的代码中使用并行选项或异步方法来加速你的代码执行。

PS:我个人没有对应用程序池属性进行更改以验证它是否有效。

【讨论】:

  • 感谢您抽出宝贵时间做出此回复。但是,这对我来说不是可行的解决方案。当队列填满时,这将终止新传入的请求。因此新请求得到 503 错误。我需要将新传入的请求放入队列并等待线程空闲来处理它。而且我正在寻找一种在 ASP.NET 工作人员之前执行此操作的选项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-19
  • 1970-01-01
相关资源
最近更新 更多