Asp.net应用程序运行缓慢但CPU最高为40%

时间:2010-11-19 16:30:06

标签: asp.net performance crash-dumps

我在生产服务器上遇到奇怪的情况。 asp.net的连接排队,但CPU只有40%。此外,数据库在30%CPU下运行良好。

评论中要求的更多历史记录:

  • 在高峰时段,网站每小时约有20,000名访客。
  • 该网站是一个带有大量AJAX / POST的asp.net webforms应用程序
  • 该网站使用了大量用户生成的内容
  • 我们使用测试页来测量站点的性能,该测试页确实击中了数据库和站点使用的Web服务。此页面在正常负载下一秒钟内即可获得服务。当请求超过4秒时,将应用程序定义为慢速。
  • 根据测量结果,我们可以看到连接时间很快,但处理时间很长。
  • 我们无法确定单个请求的响应速度慢,网站在正常时间运行正常但在高峰时段运行缓慢
  • 我们遇到了网站受CPU限制(也就是100%运行)的问题,我们修复了
  • 我们也遇到了appdomain重启的例外问题,我们修复了
  • 在高峰时段,我会看一下asp.net的性能指标。我们可以看到我们有600个当前连接和500个排队连接的行为。
  • 在高峰时段,CPU大约为40%(这让我认为它不受CPU限制)
  • 物理内存使用率约为60%
  • 在高峰时间,DatabaseServer CPU约为30%(这使我认为它不受数据库限制)

我的结论是其他东西阻止服务器更快地处理请求。可能的嫌疑人

  • 死锁(!syncblk只提供一个锁)
  • 磁盘I / O(通过sysinternals procesexplorer检查:3.5 mB / s)
  • 垃圾收集(峰值期间10~15%)
  • 网络I / O(连接时间仍然很低)

要了解我为minidumps创建的进程正在做什么。

我设法创造了两个相隔20秒的MemoryDump。这是第一个的输出:

!threadpool
CPU utilization 6%
Worker Thread: Total: 95 Running: 72 Idle: 23 MaxLimit: 200 MinLimit: 100
Work Request in Queue: 1
--------------------------------------
Number of Timers: 64

和第二个的输出:

!threadpool
CPU utilization 9%
Worker Thread: Total: 111 Running: 111 Idle: 0 MaxLimit: 200 MinLimit: 100
Work Request in Queue: 1589

正如您所看到的,队列中有很多请求。

问题1:队列中有1589个请求是什么意思。这是否意味着阻止某事?

!threadpool列表主要包含以下条目:     未知功能:6a2aa293上下文:01cd1558     AsyncTimerCallbackCompletion TimerInfo @ 023a2cb0

如果我深入了解AsyncTimerCallbackCompletion

!dumpheap -type TimerCallback

然后我查看TimerCallback中的对象,其中大多数都是类型:

System.Web.SessionState.SessionStateModule
System.Web.Caching.CacheCommon

问题2:这些对象是否具有计时器,这是否有意义?我应该阻止这个。怎么样?

主要问题我是否会错过任何明显的问题,为什么我排队连接而不是最大化CPU?


我在峰值期间成功制造了一个故障转储。用debugdiag分析它给了我这个警告:

Detected possible blocking or leaked critical section at webengine!g_AppDomainLock owned by thread 65 in Hang Dump.dmp
Impact of this lock
25.00% of threads blocked
(Threads 11 20 29 30 31 32 33 39 40 41 42 74 75 76 77 78 79 80 81 82 83)

The following functions are trying to enter this critical section
webengine!GetAppDomain+c9

The following module(s) are involved with this critical section
\\?\C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\webengine.dll from Microsoft Corporation

快速谷歌搜索没有给我任何结果。有人有线索吗?

5 个答案:

答案 0 :(得分:4)

处理队列的工作进程是真正的破解者。可能与在同一主机上调用webservices的网站相关联。从而造成一种僵局。

我将machine.config更改为以下内容:

<processModel
        autoConfig="false"
        maxWorkerThreads="100"
        maxIoThreads="100"
        minWorkerThreads="50"
        minIoThreads="50" />

标准此processModel设置为autoConfig =“true”

使用新配置,网络服务器正在以足够快的速度处理请求,以免排队。

答案 1 :(得分:3)

我使用的是realworldcoder:IIS的工作原理是让工作进程处理传入的请求。如果请求堆积起来,正如看起来正在发生的那样,那么性能就会下降。

有几种可能的事情要做/检查。

  1. 在SQL Server上启动活动监视器。您希望查看哪些查询花费的时间最长,并根据结果进行更改以减少执行时间。长查询可能导致页面正在执行的线程被阻塞,从而减少了您可以支持的连接数。

  2. 查看这些page / ajax调用的查询数量和执行时间。我已经看到有几十个不必要的查询的页面,这些查询只是因为.Net执行整个页面循环,即使只需要运行一个特定的方法。您可以将这些调用拆分为常规Web处理程序(.ashx)页面,以便您可以更好地控制发生的情况。

  3. 考虑增加IIS处理传入请求的工作进程数。新应用程序池的默认值为1个20 threads进程。这通常足以处理大量的请求;但是,如果请求由于等待数据库服务器或其他资源而阻塞,则可能导致管道堆叠。请记住,这可能会对应用程序的性能和常规功能产生正面或负面影响。所以做一些研究,然后测试,测试,测试。

  4. 考虑减少或取消您对会话的使用。无论哪种方式,查看它的内存使用情况,可能会为您的Web服务器添加更多内存。无论数据是否被使用,会话数据都会针对每个页面加载(包括ajax调用)进行序列化和反序列化。根据您在会话中存储的内容,它可能会对您的网站产生严重的负面影响。如果您没有使用它,请确保它在您的web.config中完全关闭。请注意,如果您将会话存储在Web服务器之外,这些问题会变得更糟,因为当页面检索并存储它时,您会受到网络速度的限制。

  5. 查看围绕JIT(即时)编译的网站性能计数器。这应该几乎不存在。我看到网站被大量的JIT瘫痪了。一旦这些页面被重新编码以消除它,网站就会再次开始飞行。

  6. 查看不同的缓存策略(我不认为会话是真正的缓存解决方案)。也许有些事情你经常要求你不需要经常退出数据库服务器。我的一个朋友有一个网站,他们将整个网页缓存为动态内容的物理文件,包括他们的讨论组。这大大提高了他们的表现;但这是一个重大的架构变化。

  7. 以上只是几个要看的内容。您基本上需要进一步了解详细信息,以确切了解发生了什么,并且大多数常规性能计数器都不会为您提供清晰度。

答案 2 :(得分:2)

太多的ASP.NET排队请求会破坏性能。请求线程数量非常有限。

尝试通过异步处理页面的慢速部分来释放这些线程,或者做任何其他事情来减少页面执行时间。

答案 3 :(得分:1)

我知道这是一个旧帖子,但它是ASP.NET网站性能较差的人首次点击谷歌之一。所以我会抛出一些建议:

1)异步编程将解决根本原因。当您呼叫Web服务来执行您的实际业务逻辑时,这些请求线程只是坐在那里等待响应。可以使用它们代替服务另一个传入请求。如果不完全消除它,这将显着减少您的队列长度。异步编程是关于可伸缩性的,而不是单个请求性能。这在使用Async/Await模式的.NET 4.5中非常容易实现。 ASP.NET以每分钟2的速率注入线程,因此除非您重新使用这些现有线程,否则您将很快用完正在接收的站点负载。此外,增加更多线程是一个很小的性能影响;它需要更多的RAM和时间来分配RAM。只是增加machine.config中的线程池大小不会解决底层问题。除非你添加更多的CPU,否则添加更多的线程并不会真正有用,因为它仍然是资源的错误分配,你也可以通过拥有太多的线程和太少的CPU来上下文切换自己。

2)From a popular article on threading in IIS 7.5:如果您的ASP.NET应用程序使用Web服务(WFC或ASMX)或System.Net通过HTTP与后端进行通信,则可能需要增加connectionManagement / maxconnection。对于ASP.NET应用程序,autoConfig功能限制为12 * #CPU。这意味着在四进制上,您最多可以与IP端点建立12 * 4 = 48个并发连接。因为这与autoConfig绑定,所以在ASP.NET应用程序中增加maxconnection的最简单方法是以编程方式从Application_Start设置System.Net.ServicePointManager.DefaultConnectionLimit。将值设置为您希望应用程序使用的并发System.Net连接数。我已将其设置为Int32.MaxValue而没有任何副作用,因此您可以尝试 - 这实际上是本机HTTP堆栈WinHTTP中使用的默认值。如果您无法以编程方式设置System.Net.ServicePointManager.DefaultConnectionLimit,则需要禁用autoConfig,但这意味着您还需要设置maxWorkerThreads和maxIoThreads。如果您没有使用经典/ ISAPI模式,则无需设置minFreeThreads或minLocalRequestFreeThreads。

3)如果你每小时获得20k的独立访问者,你应该真正关注负载平衡。如果每个用户每小时都要执行10-20个AJAX请求,那么您很容易就会向后端发出100万或更多的Web服务请求。扔掉另一台服务器会减少主服务器上的负载。将它与async / await结合起来,你就可以把自己放在一个很好的情况下,你可以很容易地把硬件扔到问题上(向外扩展)。这里有许多好处,例如硬件冗余,地理定位和性能。如果您正在使用AWS或RackSpace等云提供商,那么使用您的应用程序启动另一个虚拟机非常容易,可以通过手机完成。如今云计算太便宜甚至根本没有队列长度。即使在切换到异步编程模型之前,您也可以这样做以提供性能优势。

4)扩展:向服务器添加更多硬件帮助,因为当您有其他线程时,它可以提供更好的稳定性。更多线程意味着您需要更多CPU和RAM。即使你已经掌握了异步/等待,如果可以的话,你仍然希望微调那些Web服务请求。这可能意味着添加缓存层或增强数据库系统。您不希望在该单个服务器上最大化CPU。一旦CPU达到80%,ASP.NET将停止向系统注入更多线程。如果工作进程处于0%并不重要,如果任务管理器报告的整体系统CPU利用率达到80%,则线程注入停止并且请求开始排队。当垃圾收集检测到服务器上的CPU负载很高时,也会发生奇怪的事情。

答案 4 :(得分:0)

有人能证实这对他们有用吗?我在网上找到了答案,并且零回复确认已发布的答案为他们解决了这个问题。话虽如此,我并没有真正给它可信度,因为问题海报提供了答案。

我最近遇到了同样的问题:

  

检测到可能阻塞或泄漏的关键部分   webengine!g_AppDomainLock由16号线程拥有   w3wp.exe__DefaultAppPool__PID__3920__Date__04_26_2011__Time_10_40_42AM__109__IIS_COM +   Hang Dump.dmp        这个锁的影响

     

4.17%的线程被阻止        (主题17)        以下函数正在尝试进入此关键部分webengine!GetAppDomain + c9        以下模块涉及此关键部分\?\ c:\ WINDOWS \ microsoft.net \ framework \ v2.0.50727 \ webengine.dll来自   微软公司

这是Microsoft发布的进一步排除故障的建议:

  

以下供应商已确定基于root进行跟进   原因分析微软公司        请跟进上面提到的供应商。请考虑以下方法来确定此关键部分的根本原因   问题:

     
      
  1. 在Application Verifier中启用“锁定检查”    A.从以下URL下载Application Verifier:http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c4a25ab9-649d-4a1b-b4a7-c9d8b095df18&displaylang=en         B.通过运行以下命令为此进程启用“锁定检查”:

         

    Appverif.exe -enable locks -for w3wp.exe      C.有关Application Verifier的更多信息,请参阅以下文档:   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnappcom/html/appverifier.asp?frame=true

  2.   
  3. 使用DebugDiag崩溃规则来监视应用程序的异常

  4.