2013-09-01
一个ASP.NET项目在部署到生产环境时,当用户并发量达到200左右时,IIS出现了明显的请求排队现象,发送的请求都进入等待,无法及时响应,系统基本处于不可用状态。因经验不足,花了很多时间精力解决这个问题,本文记录了我查找问题的过程和最后解决方案,供大家参考。
软硬件环境:
IBM刀片服务器,Intel至强处理器,4物理核,16个逻辑核心,内存32G
Windows Server2008 Enterprise R2, ASP.NET 4.0 Webform IIS7.5 集成模式
当发现请求明显延迟,没有被即时处理的现象,首先就要查看Windows自带的性能日志Performance Monitor。
由于我注意到只有对于.aspx或.ashx的请求才会延迟,而.htm或.jpg文件都是即时响应的,所以很明显问题出在ASP.NET上,于是我选择了性能监视器中的ASP.NET 4.0中的2个主要计数器: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个左右就不行了。
然后我将测试程序从sleep10秒改成3秒,对于一个应用系统来说,页面平均3秒处理时间的性能该还算比较正常了。但可惜的是,排队现象与处理时间并无太大关系,排队仍然很严重。
针对以上问题,查阅了相关资料,是否出现排队是和应用程序池的可用线程有关,通过2个方法可以查看系统总线程数和当前可用线程数。
ThreadPool.GetAvailableThreads( out availableWorker, out availableIO);
ThreadPool.GetMaxThreads(out maxWorker, out maxIO);
在队列请求数达到120左右时,通过此方法,得到maxWorker=1600,而availableWorker=1472
因为服务器是16核的,ASP.NET4.0默认每核可以使用100个线程,所以maxWorker是1600,1600-120=1480,大致相等。
就是说当前有120个线程被用来处理请求,还有1400多个处于空闲。关键问题就是为什么这些空闲线程没有被及时启用?
ASP.NET提供的线程配置参数中,有一个参数是非常重要,但是可能被大家忽略的,就是minWorkerThreads。
意指最小工作线程,根据我们以上的测试结果,IIS托管线程启动非常慢,微软也认识到了这个问题,所以提供此参数用于设置正常情况下的最小工作线程数。比如我们系统白天的并发在200-300之间,则可以设置最小线程为300,这样系统响应速度可以大幅提高。
据此,我对配置文件(machine.config)进行了如下修改。注意都是针对单个CPU的,系统会自动乘以逻辑CPU的数量。
<system.web>
<processModel autoConfig="false" maxWorkerThreads="200" minWorkerThreads="50" />
相当于最小工作线程设置成了50*16=800。
重启IIS后进行测试,我们得到了以下结果:
可以看到,由于设置了合理的最小工作线程数,使得IIS无需不断创建新线程来处理请求,系统的响应能力已可以满足并发要求。
除此之外,在IIS6之后引入了一个新功能叫Web Garden,其设计目的是为了在CPU占用较低,但是并发请求数比较多的情况下,提升服务器性能。这正符合我当前的情况,于是我启用了Web Garden,将工作进程数从1调整到5,在任务管理器中可以看到w3wp进程从原来的1增加到了5,然后重新测试。
同样的320个请求下,可以看到除了一开始的几秒出现了一些排队,后面基本上表现良好,没有请求进入队列。
通过以上两种方式,都可以有效解决本文开头提出的问题。但Web Garden是工作在多进程模式下,如果应用中用到了依赖进程的Session和Cache等对象都必须另想办法,不能保存在服务器内存中,而且Web Garden的多个进程切换时会有上下文复制,其资源消耗相对单进程要大,这些是需要考虑的因素。
奇妙商场嘉年华最新版本(改名奇妙故事创造家)下载v9.82.63.00 安卓版
其它手游 192.9M
下载天天爱消除官方下载v2.34.0.0Build13 安卓手机版
休闲益智 341.9M
下载爱玩信阳黑七游戏下载v10.50.208 安卓最新版
其它手游 96.1M
下载掌上英雄联盟ios版下载v10.12.2 iphone版
其它手游 346M
下载咪咕快游云游戏ios版下载v10.2.59 iphone版
其它手游 397M
下载罗布乐思roblox国际服最新版ios下载v2.651.836 iphone版
其它手游 258M
下载傲世西游ios版下载v2.116 iPhone版
其它手游 282M
下载宝宝甜品店宝宝巴士免费版下载v9.82.59.01 安卓版
其它手游 140.9M
下载最强NBA官方版下载v1.51.621 安卓版
下载
蛋仔派对4399版下载v1.0.168 安卓游戏盒版
下载
跑跑卡丁车官方竞速版手游下载v1.34.2 安卓版
下载
宝宝巴士世界国际版下载v10.00.75.21 官方安卓最新版
下载
王者荣耀体验服下载v10.11.13.1 安卓2024最新版
下载
2024王者荣耀前瞻版下载v10.11.13.1 安卓版
下载
宝宝奇妙世界游戏手机版(宝宝巴士世界)下载v10.00.75.21 安卓最新版
下载
nba直播ios版下载v7.17.0 iphone版
下载