在这篇博文中,我们抛开对阿里巴巴云的疑虑,从aside的角度进行分析,看看能否找到对问题现象更合理的解释。
“黑色30秒”问题现象的主要特征是:排队请求的数量突然增加,到达HTTP的请求的到达率。系统减少,QPS(请求/秒)减少,中央处理器消耗减少,当前连接数增加。
昨晚18:08左右,发生了“黑色30秒”,这只是一个案例研究。
1.为什么排队的请求会突然增加?
最直接的原因是ASP.NET没有可用的线程来处理当前的请求。为什么没有可用的线程?毕竟,ASP.NET可用的线程是有限的。可能当时并发请求太多,ASP.NET没有时间创建足够的线程来处理这些请求。
让我们来看看ASP.NET的线程相关设置,——machine.config中的processModel(位于c: windows Microsoft中。net framework 64 v 4 . 0 . 30319 config)。
有四个相关设置:maxWorkerThreads(默认值为20)、maxIoThreads(默认值为20)、minWorkerThreads(默认值为1)和miniothreads(默认值为1)。(这些设置是针对每个CPU内核的。)
我们使用默认设置,因为我们的Web服务器是8个核心,所以实际的maxWorkerThreads是160,实际的maxIoThreads是160,实际的minWorkerThreads是8,实际的minIoThreads是8。
根据此设置,如果瞬时并发请求为169,是否有队列?不,ASP.NET没那么蠢!因为CLR秒只能创建2个线程,线程用完才会创建,黄花菜凉了。我们猜测,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 排队请求,可以直观地评估ASP.NET应用的吞吐量。
2)ASP.NET async/await可以有效减少由于可用线程不足导致的请求排队问题。
2.为什么到达率会下降?
(上图橙色线)
这是“黑色30秒”问题中最令人费解的部分。到达HTTP的请求数量。请求在ASP.NET排队后系统会减少吗?起初,我们总是不相信到达率的下降是由请求的队列引起的,但监控图中有无可辩驳的证据。
在写这个博客之前,我们突然想通了!我之前忽略了一个地方——。当你键入这篇博文时,第一个请求是html页面。如果这个请求得到一个正常的响应,浏览器在加载这个页面的时候会发出多个ajax请求。如果第一个请求排队,浏览器处于等待状态,后续的ajax请求将不会被发送,因此到达HTTP的请求数量。系统将减少。这也解释了为什么到达率有时会在“黑色30秒”的中间阶段上升,正是因为当时排队的请求对应的页面中有很多ajax。在它完成排队并被执行之后,许多后续的ajax请求(可能是这样的请求)到达HTTP。[计]系统复制命令(system的简写)
因此,我们认为到达率的下降是由请求排队引起的。
[启示]
我们不应该把目光局限在眼前看到的问题上,而是要综合考虑,联系多种因素,理清各种现象之间的关系。
3.QPS下降。
与到达率的下降一样,QPS(请求/秒)与到达率直接相关并成正比。
因此,QPS也因为请求排队而下降。
4.CPU消耗减少。
同样,到达率和QPS的下降意味着中央处理器要做的工作减少,自然消耗也会减少。
因此,由于请求排队,CPU消耗也减少了。
5.电流连接上升。
当前连接是请求排队的直接表现。如果请求没有被执行,连接肯定会被保持。
因此,由于请求排队,当前连接也会增加。
6.看看一个新的指标,请求执行。
(上图中的绿线表示请求正在执行。)
在请求排队期间,ASP.NET正在执行的请求数量正在增加,这表明随着已释放线程的增加和更多新线程的创建,排队的请求正在被执行得越来越多。这从侧面表明执行线程可能是正常的,没有被卡住。(以下IIS日志信息将进一步验证这一点。)
因此,请求执行的增加也是由于请求正在排队,这表明排队是正常的,没有卡住的地方。
7.让我们看看IIS日志中请求的时间。
在“黑色30秒”阶段,IIS日志中没有耗时超过1s的请求!这是什么意思?它显示正在执行的请求非常快,没有任何东西被卡住。除了没有足够的可用线程之外,请求被排队。
因此,IIS日志显示除了请求队列之外,一切正常。
[摘要]
如果把“黑色30秒”的问题归结为ASP.NET线程问题,那么除了30秒左右的问题,其他问题都可以更合理的解释。
写这个博客之前,我们以为ASP.NET线程问题导致“黑30秒”的概率是80%,写完这7点分析之后,我们以为概率是99%,除非这个分析的“黑30秒”和之前的“黑30秒”不一样。
现在我们需要使用新的设置(maxworkerthreads=' 100 ',maxiothreads=' 100 ',minworkerthreads=' 50 ',miniothreads=' 50 ')进行验证。
大结局来了。重要的可能不是结局是什么,而是过程。我们分享的是解决问题的过程。