12

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

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

  • 在高峰时段,这些网站每小时约有 20,000 名访问者。
  • 该站点是一个带有大量 AJAX/POST 的 asp.net 网络表单应用程序
  • 该网站使用大量用户生成的内容
  • 我们使用一个测试页面来衡量网站的性能,该页面确实会命中数据库和网站使用的 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(连接时间仍然很短)

为了找出过程在做什么,我创建了小型转储。

我设法创建了两个相隔 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 列表主要包含以下条目: Unknown Function: 6a2aa293 Context: 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

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

4

5 回答 5

4

处理队列的工作进程是真正的破坏者。可能与在同一主机上调用 web 服务的网站连接。从而产生了一种僵局。

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

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

标准此 processModel 设置为 autoConfig="true"

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

于 2010-12-10T13:05:27.740 回答
3

我和 realworldcoder 在一起:IIS 通过让工作进程处理传入的请求来工作。如果请求堆积如山,看起来正在发生,那么性能就会急剧下降。

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

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

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

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

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

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

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

以上只是一些值得关注的事情。您基本上需要进一步了解细节以准确了解发生了什么,并且大多数常规性能计数器不会让您清楚。

于 2010-11-23T15:44:01.800 回答
2

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

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

于 2010-11-20T15:06:11.060 回答
2

我知道这是一个旧线程,但对于 ASP.NET 网站性能不佳的人来说,它是 Google 的第一批热门话题之一。所以我会抛出一些建议:

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

2) 来自一篇关于 IIS 7.5 中线程的热门文章:如果您的 ASP.NET 应用程序使用 Web 服务(WFC 或 ASMX)或 System.Net 通过 HTTP 与后端通信,您可能需要增加 connectionManagement/maxconnection。对于 ASP.NET 应用程序,autoConfig 功能将其限制为 12 * #CPU。这意味着在 quad-proc 上,您最多可以有 12 * 4 = 48 个到 IP 端点的并发连接。因为这与 autoConfig 相关,所以在 ASP.NET 应用程序中增加 maxconnection 的最简单方法是以编程方式设置 System.Net.ServicePointManager.DefaultConnectionLimit,例如从 Application_Start。将该值设置为您希望应用程序使用的并发 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 等云提供商,那么在您的应用程序上启动另一个 VM 非常简单,可以通过您的手机完成。如今,云计算太便宜了,甚至根本没有队列长度。

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

于 2013-07-29T15:02:34.587 回答
0

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

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

在 w3wp.exe__DefaultAppPool__PID__3920__Date__04_26_2011__Time_10_40_42AM__109__IIS_COM+ 中的线程 16 拥有的 webengine!g_AppDomainLock 检测到可能的阻塞或泄漏临界区 + Hang Dump.dmp 此锁的影响

4.17% 的线程被阻塞(线程 17) 以下函数试图进入此临界区 webengine!GetAppDomain+c9 此临界区涉及以下模块 \?\c:\WINDOWS\microsoft.net\framework\微软公司的 v2.0.50727\webengine.dll

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

根据根本原因分析确定了以下供应商进行跟进 Microsoft Corporation 请跟进上述供应商。考虑以下方法来确定此关键部分问题的根本原因:

  1. 在应用程序验证程序 A 中启用“锁定检查”。从以下 URL 下载应用程序验证程序: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. 有关应用程序验证程序的更多信息,请参阅以下文档:http: //msdn.microsoft.com/library/default.asp ?url=/library/en-us/dnappcom/html/appverifier.asp?frame=true

  2. 使用 DebugDiag 崩溃规则来监控应用程序的异常情况

于 2011-04-28T13:39:05.527 回答