我有一个 IIS7 应用程序池,可以处理大量 RESTful 请求。当事情变得激烈时,CPU 使用率会达到 100%,并且请求需要很多秒才能处理。
在使用 ANTS 进行分析时,我们发现大部分 CPU 时间通常都花在此处:
System.Web.Hosting.PipelineRuntime.ProcessRequestNotification
System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper
(Unmanaged code)
System.Web.Hosting.PipelineRuntime.ProcessRequestNotification
System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper
System.Web.HttpRuntime.ProcessRequestNotificationPrivate
System.Web.HttpApplication.BeginProcessRequestNotification
System.Web.HttpApplication+PipelineStepManager.ResumeSteps
System.Web.HttpApplication.ExecuteStep
System.Web.HttpApplication+CallFilterExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute
System.Web.HttpResponse.FilterOutput
System.Web.HttpWriter.FilterIntegrated
System.Web.Hosting.IIS7WorkerRequest.GetBufferedResponseChunks
System.Web.Hosting.RecyclableArrayHelper.GetIntegerArray
>> System.Web.BufferAllocator.GetBuffer
(Thread blocked)
>> System.Web.BufferAllocator.ReuseBuffer
(Thread blocked)
实际上有几个不同的堆栈跟踪,但它们总是以 GetBuffer()
或 ReuseBuffer()
结尾。
GetBuffer()
和 ReuseBuffer()
都以 lock()
开头,所以我认为 CPU 花费了大量时间自旋锁(我的理解是,lock
在让线程休眠之前会旋转一段时间)。
我的问题 - 这是 CPU 花费时间的常见地方吗?这完全是 IIS 代码,那么我能做些什么来减少 CPU 负载呢?这是配置问题,还是我们的应用程序之前执行的操作的结果?
这些机器非常强大,有 4 个四核。我没有当前可用的正在运行的线程数。
最佳答案
这几乎和我们所怀疑的一样 - 线程都在自旋锁中花费了愚蠢的时间,因为它们都竞争同一个锁。我们有数百个线程。
修复方法是使用更多进程和更少线程 - 现在 CPU 使用率是合理的。
关于c# - IIS 服务器上的 CPU 在 BufferAllocator.GetBuffer() 中固定为 100%,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19164866/