IIS占用CPU百分百问题排查方案

有时候辛辛苦苦写个网站,挂到服务器上一看,CPU给百分百了,这种问题百分之八九十都是因为代码写有问题,而不是因为系统设置的问题,这种问题也比较难排查。但是结合一些工具也可以找到原因的,关于windbg的使用,好像有本关于.net调试的书,大家有兴趣可以看看,网上也有一些帖子,但关于ANTS Profiler的帖子就比较少了,大家也可以下载试用版来帮助解决问题

1 准备日志

1.1          用perfmon添加计数器日志,添加如下计数器

l         ASP.NET:所有计数器

l         Memory:所有计数器

l         Process:所有计数器和所有实例

l         Processor:所有计数器和所有实例

l         Thread:所有计数器和所有实例

l         Web service:所有计数器和所有实例

1.2          间隔改成1,单位改成秒

1.3          用鼠标右键单击这个日志名,然后单击开始。确保日志捕获了处理器利用率猛增至 100% 的那段时间内的所有数据。

2 抓Dump

2.1          用IIS Diagnostics Toolkit工具找出占用CPU高的w3wp进程ID

2.2          用windbg执行以下命令adplus –hang –p pid并抓取dump

 

3 检查日志

3.1          识别哪一个进程消耗了大部分的 CPU 时间

用perfmon打开准备好的日志文件,用鼠标右键单击图表,然后单击添加计数器。在添加计数器对话框中,从性能对象列表中选择 Process。选择从列表中选择计数器,然后从此列表框中选择 %Processor Time。选择所有实例,单击添加,然后单击关闭。

 

这将为我们提供所有处理器及其 CPU 使用情况的列表。现在您需要查清哪个进程引起了 100% 的 CPU 问题。

 

确保选中了突出显示工具按钮(黄色灯泡图标)。现在您可以滚动这些计数器,将除最接近 100% 标记的那个进程之外的所有进程全部删除。确保只选择了那些与您有关系的计数器。例如,如果您正在调试 100% 的 CPU 利用率的问题,您也许应该查找w3wp、inetinfo、其它的脱机处理的 COM 程序包/应用程序 (MTX.EXE/DLLHOST.EXE) 或者 IIS 应用程序。

3.2   找出该进程内部的那些在出现 100% 的 CPU 问题时仍然活动的线程实例

一旦您在进程级将问题隔离出来,您就可以将注意力集中在该进程内部的那些在出现 100% 的 CPU 问题时仍然活动的线程上,并试着隔离引起问题的那个线程。为此,我们添加更多的计数器来显示该进程中所有线程的 CPU 使用情况。对于本例而言,就是为w3wp进程(假设它占用CPU最高)中的所有线程添加计数器。用鼠标右键单击图表,然后单击 添加计数器。在添加计数器对话框中,从性能呢个对象列表中选择 Thread。选择从列表中选择计数器,然后从列表框中选择 %Processor Time。选择 从列表中选择实例,然后选择以 w3wp/* 开头的所有实例。单击添加,然后单击关闭。

 

这时,图表中显示在w3wp进程中的所有线程的 CPU 使用情况。

 

现在可以滚动计数器,将除最接近 100% 标记的那个线程以外的所有线程全部删除。这样我们就准确地找到了引起问题的那个线程(假设它的线程实例ID为12)。

3.3          找出导致CPU占用100%的线程ID

我们只保留实例ID 为12的线程(上一步操作留下的那个线程),它占用了最长的 CPU 时间。现在必须找出这个线程的线程 ID,然后在 WinDBG 中找到这个线程并对它进行调试。

要找出线程 ID,请用鼠标右键单击图表,然后单击添加计数器。在添加计数器对话框中,从心能对象列表中选择 Thread。选择从列表中选择计数器,然后从此列表框中选择 ID Thread。选择从列表中选择实例,然后选择实例w3wp/12(看具体情况而定)。单击添加,然后单击关闭。

 

这样我们就得到了引起问题的那个线程的 ID。选择 ID Thread 计数器。记录该计数器的最后一个值、最大值、最小值和平均值。通常这四个数是相同的。记录这个值(比如说1460),并切换到 WinDBG 应用程序。

4 找出导致CPU占用100%的相关代码

4.1          打开windbg,点击菜单File/Open Crash Dump,选择第二步用Adplus抓的dump文件

在 WinDBG 的 View 菜单上,单击 Processes and Threads。这将显示在出现 100% 的 CPU 问题时在w3wp进程内部运行的线程的一个列表。查找您在性能监视器中记录的线程 ID 号(3.3步中找到的线程ID,这个ID是十进制的,用calc换算成16进制标识)。如果在列表中找到此 ID 号(16进制),则单击选中它。单击 OK。
 

在 View 菜单上,单击 Call Stack。这时显示引起问题的那个线程的堆栈。该堆栈将有问题的方法隔离出来。一旦我们找到这个方法,我们就可以返回原代码,查看是哪行代码引起这个问题的。
 

参考链接(加粗为推荐)

调试分布式 Web 应用程序
http://www.microsoft.com/China/msdn/Archives/msdnonline/features/articles/Windebug.asp

WinDbg+SOS实例
http://recordsome.blogsome.com/2006/05/28/p68/
什么是WinDBG?
http://blog.joycode.com/gangp/articles/18088.aspx
翻译:通往WinDbg的捷径(一)
http://bbs.pediy.com/showthread.php?s=&threadid=24077

 

SOS 2.0中!StopOnException和ADPlus的结合使用
http://blog.joycode.com/tingwang/archive/
Debugging Windows Service
http://blog.joycode.com/tingwang/archive/
运行多个Windows Live Messenger实例的方法
http://blog.joycode.com/tingwang/archive/
如何使用 WINDBG 在 IIS 内调试 InProc COM 组件
http://support.microsoft.com/kb/192754
疑难解答使用 WinDbg 和 SOS 扩展 ASP.NET
http://support.microsoft.com/kb/892277/zh-cn
如何调试 Windows 服务
http://support.microsoft.com/kb/824344/zh-cn
Debugging Windows 2000 Web Applications
http://www.microsoft.com/technet/archive/interopmigration/linux/mvc/debugdst.mspx?mfr=true
Analyzing Logs from Exception Monitor
http://msdn2.microsoft.com/en-us/library/ms951771.aspx
Internet Information Services (IIS) 6.0
http://labmice.techtarget.com/windows2003/IIS/default.htm
Internet Information Services (IIS) 6.0 Resource Kit Tools
http://www.microsoft.com/downloads/details.aspx?FamilyID=56FC92EE-A
http://www.cnblogs.com/dflying/archive/
疑难解答使用 WinDbg 和 SOS 扩展 ASP.NET
http://support.microsoft.com/kb/892277/en
http://recordsome.blogsome.com/category/%e6%

posted @ 2007-06-03 12:14  蛙蛙王子  Views(8436)  Comments(2Edit  收藏  举报