最近由于受到攻击,而出现了请求超时,也不得不再次研究起了有关IIS的东东。
关于iis的相关东东,个人强烈推荐:http://www.iis.net/
出现请求超时一下就让我们想到了是访问量大或者说是服务器顶不住垃圾程序了。一般情况我们自然是去看程序有什么问题了,所以也就开始研究超时这个东东了。(注:不要否认攻击的存在,暴雨般的流量只有天上会掉下来,否则就是人为的。天上掉馅饼的事情爱相信相信去。)
出现此问题可能是因为 ASP.NET 限制的工作线程和完成端口线程的调用可以用来执行请求的数目。
通常,Web 服务的调用使用一个工作线程来执行发送请求的代码和来自 Web 服务接收回调的一个完成端口线程。但是,如果请求重定向或要求进行身份验证,呼叫可能使用多达两个工作和两个完成端口线程。因此,您可以在多个 Web 服务调用发生在同一时间时耗尽托管的 ThreadPool。
例如对于假设该 ThreadPool 仅限于 10 的工作线程和所有 10 个工作线程正在执行等待执行的回调的代码。因为到该 ThreadPool 排队的任何工作项将被阻止,直到某个线程变得可用,可以永远不会执行回调。
另一个潜在的争用,则 maxconnection 参数 System.Net 命名空间用来限制连接数。通常,按预期方式工作此限制。但是,如果很多应用程序试图在对单个 IP 地址的请求多进行一次线程可能必须等待可用连接。
若要解决这些问题,您可以以最适合您的具体情况 Machine.config 文件中调整以下参数:
- maxWorkerThreads
- minWorkerThreads
- maxIoThreads
- minFreeThreads
- minLocalRequestFreeThreads
- maxconnection
- executionTimeout
若要成功地解决这些问题,请执行下列操作:
- 限制可以为每个 CPU 的大约 12 同时执行的 ASP.NET 请求数。
- 允许 Web 服务回调自由地在 ThreadPool 中使用线程。
- 选择适当的值为 maxconnections 参数。您的选择基于 IP 地址和使用的 appdomain 的数量。
注意若要限制为每个 CPU 的 12 ASP.NET 请求的数量建议有点任意。但是,此限制证明适用于大多数应用程序。
maxWorkerThreads 和 maxIoThreads
ASP.NET 使用以下两个配置设置来限制最大的工作线程和使用的完成线程数:
<processModel maxWorkerThreads="20" maxIoThreads="20">
maxWorkerThreads 参数和 maxIoThreads 参数隐式相乘的 cpu 数量。例如对于如果两个处理器最大工作线程数是下列:
minFreeThreads 和 minLocalRequestFreeThreads
ASP.NET 还包含下列确定多少工作线程和完成端口线程必须可用于启动远程请求或 $ 本地请求的配置设置:
<httpRuntime minFreeThreads="8" minLocalRequestFreeThreads="8">
如果没有足够的线程可用,请求进行排队直到足够的线程可以自由地发出请求。因此,ASP.NET 将不会执行多个以下数量的请求在同一时间:
注意minFreeThreads 参数和 minLocalRequestFreeThreads 参数是不隐式相乘的 cpu 数量。
minWorkerThreads
作为 ASP.NET 1.0 Service Pack 3 和 ASP.NET 1.1 的 ASP.NET 还包含以下配置设置,用于确定多少工作线程可能会获得可立即向远程请求提供服务。
<processModel minWorkerThreads="1">
由该设置控制的线程可以创建多快的速度比从 CLR 的默认"线程调整"功能创建的工作线程。此设置使 ASP.NET 能够可能会突然填充到后端服务器突然突发的从客户端结束或任意位置类似的请求,将导致在队列中的请求数的突然增长的上一个 slow-down 由于 ASP.NET 请求队列的服务请求。minWorkerThreads 参数的默认值为 1。我们建议您将 minWorkerThreads 参数的值设置为下面的值。
minWorkerThreads = maxWorkerThreads / 2
默认状态下,minWorkerThreads 参数不是在 Web.config 文件或 Machine.config 文件中存在的。此设置是隐式乘以的 cpu 数量。
maxconnection
maxconnection 参数确定多少能连接到特定的 IP 地址。该参数将显示为以下形式:
<connectionManagement>
<add address="*" maxconnection="2">
<add address="65.53.32.230" maxconnection="12">
</connectionManagement>
本文内上文中讨论的参数的设置是所有在进程级别。但是,maxconnection 参数的设置应用到 AppDomain 级别。默认状态下,因为此设置适用于 AppDomain 级别可以创建两个连接的最大到特定的 IP 地址从每个 AppDomain 在您的过程中。
executionTimeout
ASP.NET 使用以下配置设置来限制请求执行时间:
<httpRuntime executionTimeout="90"/>
您还可以通过使用 Server.ScriptTimeout 属性来设置此限制。
注意如果增加 executionTimeout 参数的值,您可能还不得不修改 processModel responseDeadlockInterval 参数的设置。
建议
建议在本部分中使用的设置可能不适用于所有应用程序。但是,以下附加信息可以帮助您进行相应的调整。
如果将一个 Web 服务调用单个 IP 地址到每个 ASPX 页从 Microsoft 建议您使用以下配置设置:
- 设置 maxWorkerThreads 参数和 maxIoThreads 参数的值为 100。
- 设置要 maxconnection 参数的值 12 * N (其中 N 是您所具有的 cpu 数)。
- 设置要 minFreeThreads 参数的值 88 * N,minLocalRequestFreeThreads 参数来 76 * N。
- 将 minWorkerThreads 的值设置为 50。请记住 minWorkerThreads 不是在默认情况下配置文件中。您必须将其添加。
这些建议的一些涉及一个简单的公式,涉及在服务器上的 cpu 数。该变量类型的值,该值代表公式中的 cpu 数是 N。对于这些的设置如果您具有超线程启用,则必须使用逻辑 cpu 数而不是物理 cpu 数。 例如对于如果您有一个在四处理器服务器与启用超线程,N 的值的公式中将是 8,而不是为 4。
注意您在使用此配置时您可以执行的每个 CPU 的 12 ASP.NET 请求的最大值在同一时间,因为 100 88 = 12。因此,至少 88 * N 辅助线程和 88 * N 完成端口线程是可用的其他使用 (例如 Web 服务回调)。
例如对于您有一个带有四个处理器和启用超线程的服务器。基于这些公式,您可以使用下列值这篇文章中提到的配置设置。
<system.web>
<processModel maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50"/>
<httpRuntime minFreeThreads="704" minLocalRequestFreeThreads="608"/>
</system.web>
<system.net>
<connectionManagement>
<add address="[ProvideIPHere]" maxconnection="96"/>
</connectionManagement>
</system.net>
此外,您在使用此配置时 12 连接都是每个 CPU 每个 IP 地址的每个 AppDomain 可用的。因此,在下面的情况下很少的争用发生请求正在等待连接,并在 ThreadPool 不已用完时:
- 在 Web 主机只能有一个应用程序 (AppDomain)。
- ASPX 页的每个请求发出一个 Web 服务请求。
- 所有请求都都以相同的 IP 地址。
然而,您在使用此配置时涉及下列值之一的方案可能会使用太多的连接:
- 请求将多个 IP 地址。
- 请求会重定向 (302 状态代码)。
- 请求需要身份验证。
- 从多个 appdomain 发出请求。
在这些的方案中是一个不错的主意 maxconnection 参数和较高的值为 minFreeThreads 参数和 minLocalRequestFreeThreads 参数使用较低的值。
参考连接:
http://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/cpu