在这篇博文中,我们抛开对阿里云的怀疑,完全从ASP.NET的角度进行分析,看能不能找到针对问题现象的更合理的解释。

“黑色30秒”问题现象的主要特征是:排队的请求(Requests Queued)突增,到达HTTP.SYS的请求数(Arrival Rate)下降,QPS(Requests/Sec)下降,CPU消耗下降,Current Connections上升。

昨天晚上18:08左右发生了1次“黑色30秒”,正好借此案例分析一下。

1、为什么Requests Queued会突增?

最直接的原因是ASP.NET没有可用的线程处理当前请求。为什么会没有可用的线程呢?ASP.NET可用的线程毕竟是有限的,可能是当时瞬间的并发请求太多,ASP.NET来不及创建足够的线程处理这些请求。

我们来看一下ASP.NET中线程相关的设置——machine.config中的processModel(位于C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config)。

有4个相关设置:maxWorkerThreads(默认值是20), maxIoThreads(默认值是20), minWorkerThreads(默认值是1), minIoThreads(默认值是1)。(这些设置是针对每个CPU核)

我们用的就是默认设置,由于我们的Web服务器是8核的,于是实际的maxWorkerThreads是160,实际的maxIoThreads是160,实际的minWorkerThreads是8,实际的minIoThreads是8。

基于这样的设置,是不是如果瞬间并发请求是169,就会出现排队?不是的,ASP.NET没这么傻!因为CLR 1秒只能创建2个线程("The CLR ThreadPool injects new threads at a rate of about 2 per second. "),等线程用完时才创建,黄花菜都凉了。我们猜测ASP.NET只是根据这个设置去预测线程池中的可用线程是不是紧张,是不是需要创建新的线程,以及创建多少线程。

那什么情况下会出现“黑色30秒”期间那样的大量请求排队?假如并发请求数平时是300,突然某个瞬间并发请求数是600,超出了ASP.NET预估的所需的可用线程数,于是那些拿不到线程的请求只能排队等待正在执行的请求释放线程以及CLR创建新的线程。随着时间的推移,释放出来的线程+新创建的线程足以处理这些排队的请求,就恢复了正常。

那如何验证这个猜测呢? 修改maxWorkerThreads, maxIoThreads, minWorkerThreads, minIoThreads的设置,让ASP.NET提供更多的可用线程,目前我们采用的设置如下:

<processModel enable="true"  requestQueueLimit="5000" maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50" minIoThreads="50"/>

如果采用这个设置之后,“黑色30秒”现象几乎不出现,就能验证问题出在这个地方。现在主站www.cnblogs.com已经使用了这个设置,需要观察一段时间进行验证。

【启示】

1) 通过Windows性能监视器监视\ASP.NET\Requests Queued可以直观地评估ASP.NET应用程序的吞吐能力(throughput)。

2) 通过ASP.NET异步编程(async/await)可以有效减少可用线程紧张造成的请求排队问题。

2、为什么Arrival Rate会下降?

(上图中的橙色线条)

这是“黑色30秒”问题中最让人不解的地方,ASP.NET中请求再怎么排队,怎么会造成到达HTTP.SYS的请求数下降呢?一开始我们总是不相信是请求排队引起的Arrival Rate下降,但是监视图中却铁证如山。

写这篇博客之前,我们突然想通了!之前忽略了一个地方——当你打这篇博文时,第1个请求是html页面,如果这个请求得到正常响应,浏览器在加载这个页面时会发出多个ajax请求;如果第1个请求被排队,浏览器处于等待状态,后续的ajax请求就不会发出,这样到达HTTP.SYS的请求数就会下降。这也解释了为什么有时会在“黑色30秒”的中间阶段Arrival Rate会飙高,正是因为当时被排队的请求所对应的页面中有很多ajax,当它结束排队被执行后,后续的很多ajax请求(可能排队的很多是这样的请求)到达了HTTP.SYS。

于是,我们相信了是请求排队引起的Arrival Rate下降。

【启示】

不能把目光局限于当前看到的问题表现,而要综合考虑,将诸多因素联系起来理清各种现象之间的关系。

3、QPS下降

与Arrival Rate下降同理,QPS(Requests/Sec)与Arrival Rate是直接相关的,成正比关系。

于是,QPS下降也是因为请求排队。

4、CPU消耗下降

也是同理,Arrival Rate与QPS下降,说明CPU要干的活少了,自然消耗就下降。

于是,CPU消耗下降也是因为请求排队。

5、Current Connections上升

Current Connections是请求排队的一个直接表现,请求还没被执行,连接当然会保持着。

于是,Current Connection上升也是因为请求排队。

6、看一个新指标Requests Executing

(上图绿色的线条表示的是Requests Executing)

在请求排队的期间,正在被ASP.NET执行的请求数(Requests Executing)在增加,说明随着被释放出来的线程增多以及更多的新线程被创建,排列中的请求正在被越来越多地执行。这从侧面说明了执行中的线程可能是正常的,没有被卡住。(接下来的IIS日志信息会进一步验证这一点)

于是,Requests Executing在增加也是因为请求被排队,而且说明这个排队是正常的,没有哪个地方卡住了。

7、再来看看IIS日志中请求的time-taken

在“黑色30秒”阶段,IIS日志中没有time-taken超过1s的请求!这说明了什么?说明了正在被执行的请求处理速度很快,没有什么地方被卡住。。。除了因为可用线程不够,请求被排队。

于是,IIS日志说明除了请求排队,其他地方一切正常。

【总结】

如果把“黑色30秒”问题归因于ASP.NET线程问题,除了30秒左右的这个时间,其他问题表现都得到了更合理的解释。

写这篇博客之前,我们当时觉得ASP.NET线程问题引起“黑色30秒”问题的可能性是80%,写完这7点分析之后,我们觉得可能性是99%,除非这次分析的“黑色30秒”与之前的“黑色30秒”不是同一个问题。

现在还需要我们使用新设置(maxWorkerThreads="100", maxIoThreads="100", minWorkerThreads="50", minIoThreads="50")之后的验证。

大结局即将来临,重要的可能不是结局是什么,而是其中的过程,我们分享的也是解决问题的过程。

【“黑色30秒”相关博文】

云计算之路-阿里云上:Web服务器遭遇奇怪的“黑色30秒”问题

云计算之路-阿里云上:排查“黑色30秒”问题-为什么请求会排队

云计算之路-阿里云上:对“黑色30秒”问题的猜想

云计算之路-阿里云上:结合IIS日志分析“黑色30秒”问题

云计算之路-阿里云上:借助IIS Log Parser Studio分析“黑色30秒”问题

【参考资料】

ASP.NET Thread Usage on IIS 7.5, IIS 7.0, and IIS 6.0

Tuning IIS - machine.config settings

云计算之路-阿里云上:从ASP.NET线程角度对“黑色30秒”问题的全新分析的更多相关文章

  1. 云计算之路-阿里云上:Web服务器遭遇奇怪的“黑色30秒”问题

    今天下午访问高峰的时候,主站的Web服务器出现奇怪的问题,开始是2台8核8G的云服务器(ECS),后来又加了1台8核8G的云服务器,问题依旧. 而且3台服务器特地使用了不同的配置:1台是禁用了虚拟内存 ...

  2. 云计算之路-阿里云上-容器难容:容器服务故障以及自建 docker swarm 集群故障

    3月21日,由于使用阿里云服务器自建 docker swarm 集群的不稳定,我们将自建 docker swarm 集群上的所有应用切换阿里云容器服务 swarm 版(非swarm mode). 3月 ...

  3. 云计算之路-阿里云上-新发现:又一种与虚拟内存有关的CPU波动情况

    在云上真是无奇不有,昨天偶然间发现在IIS的应用程序池回收设置中,仅仅设置了一下基于虚拟内存限制的回收,就引发了CPU有规律的波动.在这篇博文中,我们将向大家汇报一下云计算之路上的这个小发现. 在之前 ...

  4. 云计算之路-阿里云上:启用Windows虚拟内存引发的CPU 100%故障

    今天上午11:35~11:40左右,由于负载均衡中的两台云服务器CPU占用突然飚至100%,造成网站5分钟左右不能正常访问,请大家带来了麻烦,请谅解! (上图中红色曲线表示CPU占用) 经过分析,我们 ...

  5. 云计算之路-阿里云上:SLB会话保持的一个坑

    冒着被大家厌烦的风险,今天再发一篇“云计算之路-阿里云上”.这是在前一篇发过之后真实发生的事情,我们觉得定位问题的过程值得分享.而且估计园子里不少朋友被这个问题骚扰过,我们有责任让大家知道问题的真正原 ...

  6. 云计算之路-阿里云上:原来“黑色0.1秒”发生在socket读取数据时

    在昨天的博文(云计算之路-阿里云上:读取缓存时的“黑色0.1秒”)中我们犯了一个很低级的错误——把13ms算成了130ms(感谢陈硕发现这个错误!),从而对问题的原因作出了错误的推断,望大家谅解! 从 ...

  7. 云计算之路-阿里云上:禁用Windows虚拟内存引发的重启

    昨天(2013年8月6日)下午,承载www.cnblogs.com主站的两台云服务器分别自动重启了1次,由于这两台云服务器使用了负载均衡(SLB),重启并未影响网站的正常访问. 与这次重启相关的Win ...

  8. 云计算之路-阿里云上:OCS问题的进展以及11:30-11:50遇到的问题

    (上图是今天出问题期间Web服务器性能监控图,紫色表示的是Request Execution Time) 昨天我们发布了一篇博客分享了我们这两天遇到的OCS(开放缓存服务)问题,详见云计算之路-阿里云 ...

  9. 云计算之路-阿里云上:愚人节被阿里云OCS愚

    今天是愚人节,而我们却被阿里云OCS愚,很多地方的缓存一直不过期,造成很多页面中的数据一直不更新.这篇博文将向您分享我们这两天遇到的OCS问题. 阿里云OCS(Open Cache Service)是 ...

随机推荐

  1. 设计模式(十三) 职责链(chain of responsibility)

    软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装.继承.多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累.最 ...

  2. Struts 2的拦截器(Interceptor)总结

     什么是Struts 2拦截器? 从软件构架上来说,拦截器是实现了面向方面编程的组件.它将影响了多个业务对象的公共行为封装到一个个可重用的模块,减少了系统的重复代码,实现功能的高度内聚,确保了业务对象 ...

  3. WCF 程序入门

    WCF是微软公司推出的符合SOA思想的分布式应用程序技术框架和编程模型,是建立在消息通信这一概念基础上运行的一个运行时服务系统. WCF编程模型的目标是实现以下两个实体之间的通信:WCF服务端和WCF ...

  4. StreamingAssets文件夹在不同平台上的引用

    On a desktop computer (Mac OS or Windows) the location of the files can be obtained with the followi ...

  5. 输出 n=6 的三角数字阵(JAVA基础回顾)

    package itcast.feng; import java.util.Scanner; //需求:输出 n=6 的三角数字阵 //1 //2 3 //4 5 6 //7 8 9 10 //11 ...

  6. IOS_反射

    // // PJReflect.m // 新浪微博 // // Created by pj on 14-8-8. // Copyright (c) 2014年 pj. All rights reser ...

  7. Wishart distribution

    Introduction In statistics, the Wishart distribution is generalization to multiple dimensions of the ...

  8. Windows安装和使用zookeeper

    之前整理过一篇文章<zookeeper 分布式锁服务>,本文介绍的 Zookeeper 是以 3.4.5 这个稳定版本为基础,最新的版本可以通过官网 http://hadoop.apach ...

  9. 剑指Offer面试题:30.第一个只出现一次的字符

    一.题目:第一个只出现一次的字符 题目:在字符串中找出第一个只出现一次的字符.如输入"abaccdeff",则输出'b'.要求时间复杂度为O(n). 最直观的想法是从头开始扫描这个 ...

  10. 在C#代码中应用Log4Net(一)简单使用Log4Net

    首先让我们先把Log4Net跑起来,示例代码在文章最后面可以下载 1.先把Log4Net引入到工程中,为了演示方便,我们先建立一个winform程序.在程序的根目录下面,建立一个Libs文件夹,以便存 ...