首页 - 新闻 - IIS 处理并发请求设置

IIS 处理并发请求设置

2023-10-06 10:08
-->

当一个www.gsm-guard.net项目部署到生产环境时,当并发用户数达到200左右时,IIS出现了明显的请求排队现象。所有发送的请求都在等待,无法及时响应,系统基本不可用。 。

当发现请求明显延迟,没有立即处理时,首先要检查Windows自带的性能日志Performance Monitor。

由于我注意到只有 .aspx 或 .ashx 的请求被延迟,而 .htm 或 .jpg 文件都有响应,很明显问题出在 www.gsm-guard.net 上,所以我选择 Performance Monitor 观察两个主要计数器在 www.gsm-guard.net 4.0 中:Requests Current(当前请求数)和 Requests Queued(排队请求数)。通过观察发现,当当前请求数达到200左右时,排队的请求数开始从0增加到50左右,如果请求数继续增加,排队的请求数也会增加。当排队请求数>0时,意味着此时如果访问任何.aspx页面,该页面都会等待很长时间而没有任何响应。在 IIS 处理完其他请求之前,它不会开始处理队列中的请求。也就是说,当队列数长时间>0时,系统基本处于不可用状态。

由于本系统的页面布局比较复杂,大量使用Ajax+.ashx方法来批量显示页面上的内容,所以对服务器的请求总数会比传统的aspx多模式,全部在一页上可能需要 5-10 秒才能完成加载,但我认为这应该不是问题的主要原因。即使系统性能较差,IIS也应该足以承受这么小的并发量。

为了探究到底是系统编写的问题还是IIS本身的问题,我把我们的系统放在一边,写了一个简单的页面,就一个aspx文件,在page_load中sleep了10秒。假设这是一个性能较差的网站。每页显示时间为 10 秒。我把它部署在IIS上来测试它的性能。我使用 Microsoft Web Application Stress Tool 模拟为每个连接启动 80 个线程。有 4 个 Socket,相当于总共 320 个并发请求。

测试开始后,从下图可以看到,当前请求数立即攀升至300左右(图中红线),随后队列中的请求数也上升至300左右(绿色)图中的一行),这意味着当并发请求达到 300 个后,几乎所有请求都在排队,系统基本不可用。通过简单的测试,已经重现了这个问题。

随着时间的推移,发现绿线在慢慢减少,从300条减少到100多条,这意味着系统可用性正在逐步提高。部分用户可以正常使用,但大部分仍在排队等待。

6、7分钟后,队列中的请求数下降到0左右,略有波动。此时大部分请求都可以正常处理。根据这个现象分析,应该是IIS发现队列中有大量请求,会尝试增加处理线程数来满足要求,但增长速度有些慢。

是不是意味着系统经过6、7分钟的适应期后,以后就能在这个并发下稳定运行了?但事实上并非如此。我停止了压力测试几秒钟。当服务器请求数下降到0时,我以320个请求重新开始测试。 IIS 的表现如何?从下图可以看出,只要请求数量明显增加,等待队列又开始达到最高值,然后慢慢减少,重复上述过程。综上所述,当发生大并发时,IIS处理请求的能力跟不上,需要很长时间才能打开足够的线程。

然后我做了一个测试,看看IIS默认可以处理多少个请求而不需要排队?好像是100并发左右,性能还可以,没有排队。

如果有200左右就不行了。

然后我把测试程序从睡眠10秒改为3秒。对于一个应用系统来说,平均页面处理时间3秒应该是比较正常的。但遗憾的是,排队现象与办理时间关系不大,排队现象依然严重。

ThreadPool.GetAvailableThreads(出availableWorker,出availableIO);

ThreadPool.GetMaxThreads(出maxWorker,出maxIO);

当队列请求数达到120左右时,通过该方法,maxWorker=1600,availableWorker=1472

由于服务器有16个核心,www.gsm-guard.net 4.0默认每个核心可以使用100个线程,因此maxWorker为1600,1600-120=1480,大致相等。

也就是说,目前有120个线程用来处理请求,还有1400多个是空闲的。关键问题是为什么这些空闲线程没有及时激活?

在www.gsm-guard.net提供的线程配置参数中,有一个参数非常重要,但可能被大家忽略,那就是minWorkerThreads。

表示最小工作线程数。根据我们上面的测试结果,IIS托管线程启动速度非常慢。微软也意识到了这个问题,所以提供了这个参数来设置正常情况下的最小工作线程数。例如,如果我们系统白天的并发量在200-300之间,我们可以将最小线程设置为300,这样系统的响应速度就可以得到很大的提升。

据此,我对配置文件(machine.config)进行了如下修改。注意,它们都是针对单个CPU的,系统会自动乘以逻辑CPU的数量。


相当于设置最小工作线程为50*16=800。

重新启动IIS并测试后,我们得到以下结果:

可以看出,由于设置了合理的最小工作线程数,IIS不需要不断创建新的线程来处理请求,系统的响应能力能够满足并发要求。

此外,IIS6之后引入了一个名为Web Garden的新功能,旨在提高CPU占用率较低但并发请求数较大时的服务器性能。这符合我现在的情况,于是我启用了Web Garden,并将worker进程数从1调整为5,在任务管理器中可以看到w3wp进程从1增加到5,然后重新测试。

同样是32​​0个请求,可以看到除了前几秒有一些队列外,性能基本不错,没有请求进入队列。

通过以上两种方法,可以有效解决本文开头提出的问题。然而,Web Garden以多进程模式工作。如果应用程序使用了Session、Cache等依赖于进程的对象,则必须单独找到它,并且不能将其保存在服务器内存中。而且,当Web Garden的多个进程切换时,会出现上下文复制。 ,其资源消耗比单个进程要大。这些都是需要考虑的因素。

-->