【问题标题】:IIS worker process (w3wp.exe) shoots to 99% CPU when WCF service is invoked调用 WCF 服务时,IIS 工作进程 (w3wp.exe) 会占用 99% 的 CPU
【发布时间】:2011-12-08 19:18:32
【问题描述】:

我们有一个托管在 IIS 6.0 上的 .NET 3.5 WCF 服务,它有一个 basicHttp 绑定。这由 2 个 .NET 和 2 个 ASP 应用程序使用。当第 4 个应用程序(无论是 .NET 还是 ASP)启动并尝试使用它时,w3wp.exe 会在 99% 处达到峰值,并在几秒钟后停留在那里。

基于此article,我们尝试将以下内容添加到 .NET 2.0 machine.config 中,但这没有任何效果。

<processModel autoConfig="false" maxWorkerThreads="500" maxIoThreads="500" minWorkerThreads="2"/>
<httpRuntime minFreeThreads="250" minLocalRequestFreeThreads="250"/>

有什么想法吗?

编辑:添加崩溃分析报告信息:

警告 1:w3wp.exe_v2.0 应用程序中的以下线程_PID_2856_Date__12_08_2011__Time_12_13_39PM_876_Manual Dump.dmp 正在等待同步 WCF 请求执行 4.35% 的线程被阻塞

请单击实际线程以查看 WCF 线程或查看 WCF 请求报告以找出该线程正在等待的实际 WCF 线程的线程 ID。有关此 WCF 行为的更多详细信息,请查看有关 WCF 请求限制和服务器可扩展性的博客。

Thread 16 - System ID 3920
Entry point   mscorwks!ThreadpoolMgr::intermediateThreadProc 
Create time   12/8/2011 12:10:44 PM 
Time spent in user mode   0 Days 00:00:00.031 
Time spent in kernel mode   0 Days 00:00:00.140 

This thread is waiting on a synchronous WCF request to execute

The destination WCF Thread for this ASP.NET worker thread is 14


.NET Call Stack
Function 
System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean) 
System.Threading.WaitHandle.WaitOne(Int64, Boolean) 
System.Threading.WaitHandle.WaitOne(Int32, Boolean) 
System.Threading.WaitHandle.WaitOne() 
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(System.Web.HttpApplication, Boolean) 
System.ServiceModel.Activation.HttpModule.ProcessRequest(System.Object, System.EventArgs) 
System.Web.HttpApplication+SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef) 
System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception) 
System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object) 
System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest) 
System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest) 
System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr, Int32) 

【问题讨论】:

  • 要尝试将 IIS 处理与 WCF 服务所做的工作隔离开来,请创建服务的 Windows 服务托管版本,并查看它在类似负载下是否表现出相同的行为。如果是这样,则服务中的负载会触发 CPU 密集型工作。如果没有,那么您知道您有一个 IIS 优化问题,可以通过迁移到 IIS 7 来解决 :)
  • @SixtoSaez:这似乎是个好主意,但考虑到它的大小,在现阶段将其转换为 Windows 服务(或迁移到 IIS 7)是不切实际的。我希望这可能更多地是关于 ASP.NET 工作线程与 WCF IO 线程对话方式的线程管理问题。

标签: .net wcf iis-6


【解决方案1】:

听起来您的负载以某种方式生成了大量线程,从而导致 CPU 疯狂地工作以跟上它们的速度。由于您的编辑引用了故障转储,因此您可以使用 WinDbg 找出发生了什么。

如果您熟悉 WinDbg 并已安装和配置 (otherwise spend some quality time with the tutorials here),请尝试以下操作:

.loadby sos mscorwks
.prefer_dml 1
!threads

这将显示创建了多少线程。 .prefer_dml 1 可以生成类似 HTML 的链接,因此您只需单击即可在输出中运行适当的命令。下一次运行:

!syncblk

查看哪些线程可能被阻塞。它应该 show which thread 正在阻止。如果是罪魁祸首,接下来运行类似这样的操作来获取线程 32 的堆栈:

~32e!clrstack

它应该包含有关在执行阻塞的线程上运行的代码的信息。说使用 WinDbg 非常陈旧是一种轻描淡写的说法,但值得努力帮助调试像您这样的问题。祝你好运!

【讨论】:

  • 感谢您的回答。我没有使用过 WinDbg(在获取它的过程中),但如果它只显示阻塞线程及其堆栈跟踪,那不是我的 OP 中的内容。我知道线程 16 是罪魁祸首,从 .NET 堆栈跟踪中,HostedHttpRequestAsyncResult.ExecuteSynchronous 正在等待 IO 线程 14。我只是不确定 IO 线程在做什么。 WinDbg 在这方面会有所帮助吗?
  • 我不清楚问题中的堆栈跟踪属于哪个线程。如果堆栈跟踪是针对线程 16 的,那么它本身就在等待某些东西(线程 14?)。否则,请查看线程 14 的堆栈跟踪以了解它在做什么。希望 !syncblk 输出有助于确定任何涉及死锁的线程。假设您知道要施放哪个咒语,这就是使用 WinDbg 真正有帮助的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
  • 2017-08-21
  • 2015-10-30
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多