原文地址:http://www.cnblogs.com/hgamezoom/p/3082538.html

一个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的多个进程切换时会有上下文复制,其资源消耗相对单进程要大,这些是需要考虑的因素。

(转)IIS处理并发请求时出现的问题及解决的更多相关文章

  1. IIS处理并发请求时出现的问题及解决

    一个ASP.NET项目在部署到生产环境时,当用户并发量达到200左右时,IIS出现了明显的请求排队现象,发送的请求都进入等待,无法及时响 应,系统基本处于不可用状态.因经验不足,花了很多时间精力解决这 ...

  2. IIS处理并发请求设置

    一个ASP.NET项目在部署到生产环境时,当用户并发量达到200左右时,IIS出现了明显的请求排队现象,发送的请求都进入等待,无法及时响应,系统基本处于不可用状态.   当发现请求明显延迟,没有被即时 ...

  3. iis如何处理并发请求

    文章:IIS是怎么处理同时到来的多个请求的? 文章:你真的了解:IIS连接数.IIS并发连接数.IIS最大并发工作线程数.应用程序池的队列长度.应用程序池的... 文章:IIS最大工作进程数设置引发串 ...

  4. Oracle索引失效问题:WHERE C1='' OR C2 IN(SubQuery),并发请求时出现大量latch: cache buffers chains等待

    问题描述: 项目反馈某功能响应时间很长,高峰期时系统整体响应很慢... 获取相应的AWR,问题确实比较严重,latch: cache buffers chains等待,因为这些会话SQL执行时间太长, ...

  5. iOS 如何解决并发请求时,只接受最后一个请求返回的结果

      大致意思是 虽然NSOperation 的cancel 并不能取消请求,但是可以对这个NSOperation进行标记. 当cancel 属性是YES时,表明 NSOperation虽然已经执行,并 ...

  6. 关于.Net Core 前后端分离跨域请求时 ajax并发请求导致部分无法通过验证解决办法。

    项目中有这样一个页面.页面加载的时候会同时并发6个ajax请求去后端请求下拉框. 这样会导致每次都有1~2个“浏览器预请求”不通过. 浏览器为什么会自动发送“预请求”?请看以面连接 https://b ...

  7. mock请求时出现中文乱码的解决

    请求返回的乱码如图: 原mock代码如下 [ { "description":"这是我们的第一个mock例子", "request":{ & ...

  8. Glassfish在SpringMVC服务端接收请求时字符出现乱码的解决办法

    环境描述 前端:jsp 后端:SpringMVC Controller 尽管jsp页面已设置了pageEncoding: <%@page contentType="text/html& ...

  9. PHP实现并发请求

    后端服务开发中经常会有并发请求的需求,比如你需要获取10家供应商的带宽数据(每个都提供不同的url),然后返回一个整合后的数据,你会怎么做呢? 在PHP中,最直观的做法foreach遍历urls,并保 ...

随机推荐

  1. flask之flask-restful

    0.需要的库flask_restful from flask import Flask from flask_cors import CORS 1.参数的获取self.parser.add_argum ...

  2. 容器中跨主机的网络方案-Weave

    容器中的网络是建立docker集群的重要内容. 本文将介绍如何用Weave实现容器的多节点互通. Weave是一个开源的项目,其网站为: https://www.weave.works/ 其工作原理相 ...

  3. FPGA与嵌入式一点见解

    FPGA:即现场可编程门阵列,它是在PAL.GAL.CPLD等可编程器件的基础上进一步发展的产物.它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可 ...

  4. windows-x64下安装python3.6

    1.下载python3安装包,注意要安装windowsx64的exe安装包.python-3.6.2-amd64.exe 2.设置window的环境变量:C:\Users\您设置的windows用户名 ...

  5. 3 SpringBoot与微服务

    SpringBoot的使用? 化繁为简: Spring MVC 需要定义各种配置,配置文件多. SpringBoot的核心功能? 独立运行: java -jar XXX.jar (以前启动SPring ...

  6. PHP文件操作(三)-文件的写入

    fwrite()  //对文件进行写入 fwrite(file,string,length)file:必选项,需要写入的文件string:必选项,规定要写入文件的字符串length:可选项,规定要写入 ...

  7. 用exp、dmp导入导出用户到同一个实例下时,类型type会有问题

    oralce的type都有唯一id,在同一个实例下,通过导入导出方法创建type时,会有唯一性问题 最好的解决方法使用impdb,expdb的方式导入导出 用oid=n解决. 实在不行,可用稍微麻烦的 ...

  8. Android 截屏检测

    最近项目中新接到一个需求,对手机截屏进行检测并进行后续操作,类似于Snapchat,iOS具有先天优势,因iOS系统提供了相关API!Google无果之后原作者决定再次造轮子,为了持续表达对Rx的敬意 ...

  9. JAVA的对称加密算法AES——加密和解密

    出自: http://blog.csdn.net/hongtashan11/article/details/6599645 http://www.cnblogs.com/liunanjava/p/42 ...

  10. CSS中盒子垂直居中的常用方法

    在前端开发过程中,盒子居中是常常用到的.其中 ,居中又可以分为水平居中和垂直居中.水平居中是比较容易的,直接设置元素的margin: 0 auto就可以实现.但是垂直居中相对来说是比较复杂一些的.下面 ...