Win7 IIS 最大并发请求数及其请求处理流程

“Win7 专业版 下 IIS 7.x 工作进程(worker process)并发处理的最大请求数是 10。” 如果需要提高并发处理的请求数,请使用 Windows Server 版本的操作系统。

这个结论本身并没有值得争议的地方,毕竟这是微软的一个限制。但是要真正明白这个限制,却并非这么简单。何谓真正明白?首先,你是否清楚 “并发请求” 和 “并发连接” 的区别?是否清楚这个限制与操作系统的关系?是否清楚这个限制是针对什么而言?一个IIS还是IIS中的一个应用程序池还是一个工作进程?如何去验证这个限制?

本文,我尽量用简单的方式向大家介绍以上几个问题。

并发连接数

什么是并发连接数?这个连接指的又是什么连接?并发又是指什么?它与半开连接数又是什么关系?

这里的 “连接” 并非是指外设和电脑的连接,而是指基于TCP的连接 (比如当我们的电脑作为一台 FTP 服务器时,多个不同的客户端可以同时连接到我们的电脑)。

“并发” 指的是同一时刻已经建立的连接。


什么是半开连接

半开,就是半打开的意思。因为 TCP 建立连接需要三次握手,只要这三次握手没有完全结束(比如 A 要和 B 建立连接,A 只发一个 SYN,B 还没有回复,此时 对于 A 来说该连接就是半打开状态。而 B 刚收到一个 SYN,还没有发送 ACK,也是半打开状态),就属于半开连接

所以半开连接就是指正在建立中的连接,限制半开连接数,也就是限制同时正在建立中的连接,即并发连接数。

微软在 Vista SP2 之前都有限制为 10,目的是为了防止大量恶意的连接请求。但是后来微软意识到这样做并没有什么卵用,于是从 SP2 开始取消了该限制。

SP2 removes the limit of 10 half open outbound TCP connections. By default, SP2 has no limit on the number of half open outbound TCP connections.

--- <Half-Open Outbound TCP Connections Limit Removed in Windows 7 and Vista SP2>



如何修改最大并发连接数

可以通过选择 Web Site,Advanced Settings -> Connection Limits 来进行修改,默认为 4294967295。


假设我们设置最大并发连接数为1000,现在有1000个客户端尝试与 Web 服务器连接,则就会有 1000 个连接。此时第 1001 个用户试图发起请求的时候,由于连接已经饱和,客户端会收到一个 503 错误。这也是为了保护服务器不受 DDos 攻击的一个办法。

大家要注意的是1000个连接并不意味着会有 1000 请求被同时处理,同一时刻到底有多少请求被处理取决于最大的并发请求数。

什么是工作进程

工作进程(worker process)是 IIS 6.0 开始的新能力,简单来讲就是用于隔离不同的网站,以避免因为某个网站崩溃导致其它网站遭殃。通过进程级别的隔离就大大增强了网站的稳定性和安全性。

默认情况下,工作进程只有1个,但是可以有多个,俗称的 Web 园(Web Garden)。当有多个工作进程的话,有点类似于负载均衡的功能,请求会被分配到不同的工作进程去进行执行(这个就要求网站最好是被设计成无状态的,不然在多个进程间切换可能导致状态混乱)。


如何修改最大工作进程数

*每个工作进程都会消耗较多的内存,因此设置需要谨慎。

队列是什么鬼

我们说的IIS队列,实际指的是 IIS 中每个应用程序池的队列。当请求抵达 IIS 时,首先会把请求放到对应的队列中等待处理,其作用是为了防止过多的请求一下子占用大量服务器资源而导致服务器崩溃。当超出限制的队列长度时,客户端就会收到 503 错误(HTTP Error 503. The service is unavailable)。

Application pool queue-length limits prevent large numbers of requests from queuing up and overloading your server. When application pool queue-length limits are enabled, IIS monitors the number of requests for a designated application pool queue before queuing a new request. If adding the new request to the queue exceeds the queue size, the server rejects the request and sends an uncustomizable 503-error response to the client.


---《Configuring Application Pool Queue-Length Limits


如何修改队列长度

因为这个是属于应用程序池的一个属性,因此选择应用程序池,然后点击 Advanced Settings -> Queue Length,默认为 1000.


并发请求数

我在上面说过从 Windows Vista SP2 开始,IIS 已经不会限制并发连接数了(在 Vista 之前的 XP,IIS 限制为最大连接数 = 10),转而限制最大并发请求数,也就是同一时刻处理的请求数。这意味着,当连接数超过 10 的时候,不会报错,但是超过部分的请求会保留在队列中,直到当前的请求处理完。

The only restrictions we have on Windows Vista is the number of concurrent requests IIS will execute. This is fundamentally different from the Windows XP connection limit. By limiting concurrent requests you will probably never see an error message. Request that cannot be handled because the concurrent request limit is reached will still be queued.

---《Understanding IIS7 Request Restrictions on Windows Vista

由于没有在 MSDN 上找到针对 Win7 的说法,这里直接引用针对 Vista 的说法:

在 Starter\Home Basic\Home Premium 版本中,IIS 7 支持的最大并发数为 3。

在 Business\Enterprise\Ultimate 版本中, IIS 7 支持的最大并发数为 10。

在 Server 版本中,理论上没有限制。


虽然没有在 MSDN 上找到,但是确实有朋友提到 Win7 不同版本下的 IIS 限制:

Windows 7IIS v7.5  Note 2
Starter:No IIS
Home Basic:No IIS
Home Premium:simultaneous request execution limit of 3, allows multiple sites
Business:simultaneous request execution limit of 10, allows multiple sites
Enterprise:simultaneous request execution limit of 10, allows multiple sites
Ultimate:simultaneous request execution limit of 10, allows multiple sites


*请注意,上述所说的最大并发数是针对一个应用程序池而言的(,不是针对一台 Web 服务器)。也就是说,当有2个应用程序池(分别对应2个网站),每个应用程序池最多同时处理10个请求,2个应用程序池最多同时处理20个请求。

*经测试,VS2012 自带的 IIS Express 可以支持最高 80。

请求处理流程

我没有找到官方关于 IIS 7.x 集成(Integrated)模式下处理请求的流程,只找到了 IIS 6 的处理流程,但这两者应该变化不大:

Before an IIS process receives a request to execute, some preliminary processing occurs that is described in the following steps:

  1. A request arrives at HTTP.sys.

  2. HTTP.sys determines if the request is valid. If the request is not valid, it sends a code for an invalid request back to the client.

  3. If the request is valid, HTTP.sys checks to see if the request is for static content (HTML) because static content can be served immediately.

  4. If the request is for dynamic content, HTTP.sys checks to see if the response is located in its kernel-mode cache.

  5. If the response is in the cache, HTTP.sys returns the response immediately.

  6. If the response is not cached, HTTP.sys determines the correct request queue, and places the request in that queue.

  7. If the queue has no worker processes assigned to it, HTTP.sys signals the WWW service to start one.

  8. The worker process pulls the request from the queue and processes the request, evaluating the URL to determine the type of request (ASP, ISAPI, or CGI).

  9. The worker process sends the response back to HTTP.sys.

  10. HTTP.sys sends the response back to the client and logs the request, if configured to do so.

--- MSDN <IIS Request Processing>

我们只需要关注高亮的部分,翻译如下:

如果无法在缓存中找到响应消息, HTTP.sys 会决定哪个是正确的队列,然后把请求消息放置到该队列中。

如果该队列并没有绑定任何工作进程,HTTP.sys 则触发一个 WWW 服务来启动一个。

工作进程随后从队列中取出一个请求消息并进行处理,根据 URL 来决定是什么样类型的请求。


结合我们上述关于连接数的描述及官网对 IIS 请求流程的介绍,可以知道,客户端首先会与 IIS 建立 TCP 连接,然后 “请求” 通过这些连接发送到 IIS,IIS 在接收到这些 “请求” 后,先会把它们放入队列中,然后再由工作进程去队列中取出 “请求” 进行处理

举个例子:假设 100 个用户同时发起请求,则 IIS 当前的并发连接数即为 100,随后这 100 个请求被放入队列中,工作进程再从队列中取走请求进行处理。在 Win7 专业版中,由于系统限制,工作进程最多一次性从队列中取走10个请求进行处理。


如何验证

1,这个需要借助几个性能计数器(Performance Counter):

Web Service/Current Connections 监控某个应用程序池来指示当前该应用程序池的连接的数量。

ASP.NET Apps v4.0.30319/Requests Executing 监控所有的 ASP.Net 4.0 正在处理中的请求数量。

ASP.NET v4.0.30319/Requests Current 与上述类似用于监控 Asp.Net 4.0 正在处理中的请求数量。

HTTP Service Request Queues/CurrentQueueSize 用来监控某个应用程序池当前队列中请求的个数。


还有几个其它的性能计数器,也可以使用:

ASP.NET Apps v4.0.30319/Requests In Application Queue

ASP.NET v4.0.30319/Requests Queued


*记住,性能计数器的采样周期为:1次/秒


2,测试环境准备

新建一个最简单的 “WCF Service Application” 项目,然后修改 Service1.svc.cs 中的代码,在 GetData 方法中增加一句 Thread.Sleep(1000) 从而确保在一次采样周期内请求未被处理完。

最终代码如下:

namespace WcfService1
{
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            Thread.Sleep(1000);
            return string.Format("You entered: {0}", value);
        }
        
        //省略部分无关代码
    }
}


默认的绑定为 basicHttpBinding,由于其不支持会话(session),所以相应的 InstanceContextMode 为 PerCall,ConcurrencyMode 为 Multiple,关于这部分可参考我之前写的《》。


测试工具,我这里选择 SoapUI,因为它提供的 LoadTest 可以很方便的来模拟多用户并发请求的环境。

请注意图中的黄色部分,其中 Threads 即用于模拟并发的用户数,而 Test Delay 用于表示同一个用户前后两次发请求的间隔,我们使用 0 来表示无间断。


至于测试机器,我使用的是两台 Win7 professional 的台式机,其中一台作为 Web 服务器(将 WCF 在 release 模式下部署到IIS,确保该 WCF 项目使用单独的应用程序池)。另一台作为客户机,使用 SoapUI 持续不断的向 Web 服务器发送请求。

*如果大家没有两台物理机,也可以在同一台机器内进行测试


3,实测数据

A,当 Threads = 5 的时候


从上图,可以看出当前的 connection 为 5,并发处理的请求数也是 5,而队列为 0.

由于 “Request Executing” 的 Scale 值(倍数)不一样,我选中该条目,从而让大家可以通过中间的几个框框直观的读出数据。另外,大家会看到有一个 Thread Count 我并未显示在图标中,原因是该值太大(40多)会造成其它值的在图标中显示的不够明显。

*通过观察 Thread Count,可以直观的知道 worker process 当前创建了多少条线程来并发的处理请求。


B,当 Threads = 10 的时候


从上图,可以看出当前的 connection 为 10,并发处理的请求数也是 10,而队列为 0.


C,当 Threads = 11 的时候


从上图,可以看出当前的 connection 为 11,并发处理的请求数则 10,而队列为 1.


D,当 Threads = 20 的时候


从上图,可以看出当前的 connection 为 20,并发处理的请求数仍旧为 10,而队列也为 10.


*理论上,必须通过进行对比测试来验证是操作系统导致的限制,但是由于本人身边没有 server 的系统,因此并未做测试。我稍后会分享官网及论坛中的一些资料来佐证我的说法。有兴趣的朋友可以将您的测试结论发我的邮箱,我会公布出来。

参考资料

IIS Request Processing

你真的了解:IIS连接数、IIS并发连接数、IIS最大并发工作线程数、应用程序池的队列长度、应用程序池的最大工作进程数 吗?

IIS 7.0 Editions and Windows

Understanding IIS7 Request Restrictions on Windows Vista

Half-Open Outbound TCP Connections Limit Removed in Windows 7 and Vista SP2

TCP half-open

Maximum number of http-requests on IIS with Windows 7

文章索引

[隐 藏]

本站采用知识共享署名 3.0 中国大陆许可协议进行许可。 ©2014 Charley Box | 关于本站 | 浙ICP备13014059号