黑色30s高并发IIS设置

在这篇博文中,我们抛开对阿里云的怀疑,完全从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个线程,等线程用完时才创建,黄花菜都凉了。我们猜测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下降。

【启示】

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

3QPS下降

 

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

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

4CPU消耗下降

 

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

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

5Current 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")之后的验证。

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

 

转载于:https://www.cnblogs.com/AmilyWilly/p/4791742.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544224.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我们可以覆盖Java中的main()方法吗?

The question is that "Can we override main() method in Java?" 问题是“我们可以覆盖Java中的main()方法吗&#xff1f;” No, we cant override the main() method in java. 不&#xff0c;我们不能覆盖java中的main()方法 。 First, we will understand what …

一文读懂MySQL查询语句的执行过程

需要从数据库检索某些符合要求的数据&#xff0c;我们很容易写出 Select A B C FROM T WHERE ID XX 这样的SQL&#xff0c;那么当我们向数据库发送这样一个请求时&#xff0c;数据库到底做了什么&#xff1f;我们今天以MYSQL为例&#xff0c;揭示一下MySQL数据库的查询过程&a…

angularJS的$http.post请求,.net后台接收不到参数值的解决方案

JS通用部分var shoppingCartModule angular.module(starter, [ionic], function ($httpProvider) {// Use x-www-form-urlencoded Content-Type$httpProvider.defaults.headers.post[Content-Type] application/x-www-form-urlencoded;charsetutf-8;/*** The workhorse; conve…

带有示例的Python列表reverse()方法

列出reverse()方法 (List reverse() Method) reverse() method is used to reverse the elements of the list, the method is called with this list (list in which we have to reverse the elements) and it reverses all elements in the list. reverse()方法用于反转列表中…

复杂度O(n)倒转链表

1 public class ListNode {2 int val;3 ListNode next;4 ListNode(int x) { val x; }5 ListNode(){}6 7 public static ListNode revese(ListNode input)8 {9 ListNode head new ListNode();//头插法的头 10 ListNode cur in…

synchronized底层是如何实现的?

作者 | 磊哥来源 | Java面试真题解析&#xff08;ID&#xff1a;aimianshi666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;想了解 synchronized 是如何运行的&#xff1f;就要先搞清楚 synchronized 是如何实现&#xff1f;synchronized 同步…

java sublist_Java Vector subList()方法与示例

java sublist向量类subList()方法 (Vector Class subList() method) subList() method is available in java.util package. subList()方法在java.util包中可用。 subList() method is used to return a set of sublist [it returns all those elements exists in a given rang…

单例模式 4 种经典实现方法

0.前言 如果你去问一个写过几年代码的程序员用过哪些设计模式&#xff0c;我打赌&#xff0c;90%以上的回答里面会带【单例模式】。甚至有的面试官会直接问&#xff1a;说一下你用过哪些设计模式&#xff0c;单例就不用说了。你看&#xff0c;连面试官都听烦了&#xff0c;火爆…

CSRF简单介绍及利用方法-跨站请求伪造

0x00 简要介绍 CSRF&#xff08;Cross-site request forgery&#xff09;跨站请求伪造&#xff0c;由于目标站无token/referer限制&#xff0c;导致攻击者可以用户的身份完成操作达到各种目的。根据HTTP请求方式&#xff0c;CSRF利用方式可分为两种。 0x01 GET类型的CSRF 这种类…

java setsize_Java Vector setSize()方法与示例

java setsize向量类setSize()方法 (Vector Class setSize() method) setSize() method is available in java.util package. setSize()方法在java.util包中可用。 setSize() method is used to set the new size of this vector and when new size (n_size) > current size …

虾皮二面:什么是零拷贝?如何实现零拷贝?

前言 零拷贝是老生常谈的问题啦&#xff0c;大厂非常喜欢问。比如Kafka为什么快&#xff0c;RocketMQ为什么快等&#xff0c;都涉及到零拷贝知识点。最近技术讨论群几个伙伴分享了阿里、虾皮的面试真题&#xff0c;也都涉及到零拷贝。因此本文将跟大家一起来学习零拷贝原理。1.…

设计模式2:工程模式(1)

什么是工厂模式? 提供一个创建一系列或相互依赖对象的接口&#xff0c;而不需指定它们具体的类。 通俗的讲就是定义了多个产品的类&#xff0c;且只有一个工厂类&#xff0c;而这个工厂类根据需求的不同&#xff0c;可以产生不同产品类的对象。 作用:主要为创建对象提供过度接…

java indexof_Java Vector indexOf()方法与示例

java indexof向量类indexOf()方法 (Vector Class indexOf() method) Syntax: 句法&#xff1a; public int indexOf(Object ob);public int indexOf(Object ob, int indices);indexOf() method is available in java.util package. indexOf()方法在java.util包中可用。 indexO…

各大框架都在使用的Unsafe类,到底有多神奇?

前言 几乎每个使用 Java开发的工具、软件基础设施、高性能开发库都在底层使用了sun.misc.Unsafe&#xff0c;比如Netty、Cassandra、Hadoop、Kafka等。Unsafe类在提升Java运行效率&#xff0c;增强Java语言底层操作能力方面起了很大的作用。但Unsafe类在sun.misc包下&#xff0…

Codis 分布式缓存部署

为什么80%的码农都做不了架构师&#xff1f;>>> 环境介绍: 1:机器三台 ,IP/hostname 如下, hostname的设置很重要zookeeper / codis的通信都会用到,所以要配置好三台机器的hosts文件. 10.221.8.220 机器的hostname为 Redis1 10.221.8.221 机器的hostname为 Redis…

treeset java_Java TreeSet Higher()方法与示例

treeset javaTreeSet类Higher()方法 (TreeSet Class higher() method) higher() method is available in java.util package. Higher()方法在java.util包中可用。 higher() method is used to return the lowest element in this TreeSet that is higher than the specified el…

怎么解决MySQL死锁问题的?

咱们使用 MySQL 大概率上都会遇到死锁问题&#xff0c;这实在是个令人非常头痛的问题。本文将会对死锁进行相应介绍&#xff0c;对常见的死锁案例进行相关分析与探讨&#xff0c;以及如何去尽可能避免死锁给出一些建议。话不多说&#xff0c;开整&#xff01;什么是死锁死锁是并…

strictmath_Java StrictMath cos()方法与示例

strictmathStrictMath类cos()方法 (StrictMath Class cos() method) cos() method is available in java.lang package. cos()方法在java.lang包中可用。 cos() method is used to return the trigonometric cosine of an angle of the given parameter in the method. Here, c…

Apache cxf JaxRs基本应用

2019独角兽企业重金招聘Python工程师标准>>> 在前一篇中&#xff0c;我们完成了《Apache cxf JaxWs基本应用》 的编写&#xff0c;我们现在实现一个Restful风格的Cxf 。 一、我们首先依旧是基于Maven project配置pom.xml的依赖 [html] view plaincopyprint? <pr…

白嫖1年阿里云,反手就搭一个Java环境

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;早上收到阿里云小姐姐的消息&#xff0c;阿里云有搞事情了&#xff0c;这次是送一年的阿里云 ECS 服务器。有便宜不占王八蛋…