排查 IIS 应用程序池中的高 CPU 问题

适用于: Internet Information Services

此疑难解答将帮助你确定 Internet Information Services (IIS) 应用程序池中持续高 CPU 的原因。 请务必记住,在 Web 应用程序处理请求时,CPU 使用率升高是正常现象。 但是,如果 CPU 使用率长时间保持很高水平(80% 或更高),则应用程序的性能将受到影响。 因此,必须了解持续高 CPU 的原因,以便尽可能解决和更正它。

场景

IIS 中应用程序池的 CPU 使用率长时间超过 90%。 测试应用程序时未遇到任何问题。 但是,一旦应用程序经受实际用户负载,CPU 就会攀升至较高百分比并保持这种状态。 若要恢复,必须重启应用程序池,但执行此操作后,CPU 使用率会再次攀升至高水平。

工具

数据收集

遇到高 CPU 使用率问题时,首先要做的是确定消耗 CPU 的进程。 可以使用 任务管理器中的“进程 ”选项卡执行此操作。 确保从所有用户选中“显示进程”复选框。 下图显示了此框已选中,并显示 w3wp.exe 使用较高 CPU 级别的进程(承载 IIS 应用程序池的进程)。

屏幕截图显示了 Windows 任务管理器。在 C P U 列下,w 3 w p 可执行文件行上突出显示 85。已选择“显示所有用户的进程”。

还可以使用性能监视器来确定哪个进程正在使用 CPU。 有关使用性能监视器的详细信息,请参阅分析性能数据

提示

如果需要确定与特定w3wp.exe进程关联的应用程序池,请打开管理命令提示符,切换到 %windir%\System32\inetsrv 文件夹 cd %windir%\System32\inetsrv 并运行 appcmd list wp。 这将显示包含在引号里的 w3wp.exe 进程标识符 (PID)。 可以将该 PID 与任务管理器中提供的 PID 匹配。

确认w3wp.exe进程 CPU 过高后,需要收集以下信息,以确定导致问题的原因:

  • 性能监视器数据收集器集。
  • w3wp.exe 进程的用户模式内存转储。

在发生 CPU 使用率过高事件期间,需要收集这两项信息。

收集性能监视器数据收集器集

性能监视器数据在确定 CPU 问题高的原因时通常至关重要。 它对于获取应用程序性能的“全面”视图也很有帮助。

Perfmon 数据可以实时查看,也可以在数据收集器集中收集以便以后查看。 若要排查 CPU 使用率过高的问题,我们需要收集数据收集器集。 若要创建用于排查 CPU 使用率过高问题的数据收集器集,请执行以下步骤。

  1. 在 Windows 控制面板中,打开“管理工具”。
  2. 双击性能监视器
  3. 展开“数据收集器集”节点。
  4. 右键单击“用户定义的”,然后选择“新建->数据收集器集”。
  5. 输入 高 CPU 作为数据收集器集的名称。
  6. 选择“手动创建”(高级)。
  7. 选择下一步
  8. 选择“ 创建数据日志”。
  9. 选中“性能计数器”复选框。
  10. 选择下一步
  11. 选择 添加 。 如果应用程序不是 ASP.NET 应用程序,请转到步骤 19。
  12. 滚动到计数器列表顶部,然后选择 .NET CLR 内存
  13. 在实例列表中选择“<所有实例>”。
  14. 选择“ 添加” ,将计数器添加到添加的计数器列表中。
  15. 从计数器列表中选择 ASP.NET,然后选择“添加”。
  16. 从计数器列表中选择 ASP.NET 应用程序
  17. <从实例列表中选择所有实例>
  18. 选择 添加
  19. 从计数器列表中展开 Process 。 (请确保展开 处理 而不是 处理器
  20. Process 对象中选择“处理器时间百分比”。
  21. <从实例列表中选择所有实例>
  22. 选择 添加
  23. 从计数器列表中展开 Thread
  24. Thread 对象中选择“处理器时间百分比”。
  25. <从实例列表中选择所有实例>
  26. 选择 添加
  27. 从实例列表中选择 ID 线程
  28. 选择 添加

对话现在应如下图所示。

显示“数据收集 0 1 属性”对话框的屏幕截图。“性能计数器”选项卡上选择了“I D 线程”。

选择“ 确定 ->下一步”。 记下数据收集器集的保存位置。 (如果需要,可以更改此位置。然后选择“ 完成”。

数据收集器集尚未运行。 若要启动它,请右键单击“用户定义的”节点下的“高 CPU,然后从菜单中选择“开始”。

创建调试诊断规则

在出现高 CPU 条件时收集用户模式进程转储的最简单方法是使用调试诊断。

下载 DebugDiag,在服务器上安装并运行它。 (你将在 安装后开始 菜单。)运行 DebugDiag 时,将显示 “选择规则类型 ”对话框。 按照以下步骤为应用程序池创建崩溃规则:

  1. 选择 “性能 ->下一步”。
  2. 选择 性能计数器 ->Next
  3. 选择“ 添加性能触发器”。
  4. 展开 “处理器 ”(而不是进程)对象,然后选择“ 处理器时间百分比”。 请注意,如果你在 Windows Server 2008 R2 上并且拥有 64 个以上的处理器,请选择 处理器信息 对象而不是 处理器 对象。
  5. 在实例列表中,选择 _Total
  6. 选择“ 添加 ->OK”。
  7. 选择新添加的触发器,然后选择“ 编辑阈值”。 显示“选择性能计数器”对话框的屏幕截图。
  8. 在下拉列表中选择“ 上图 ”。
  9. 将阈值更改为 80
  10. 输入 20 秒数。 (如果需要,可以调整此值,但请注意不要指定较小的秒数,以防止错误触发。)
  11. 选择“确定”
  12. 选择下一步
  13. 选择“ 添加转储目标”。
  14. 从下拉列表中选择 Web 应用程序池
  15. 从应用池列表中选择你的应用程序池。
  16. 选择“确定”
  17. 选择下一步
  18. 再次选择下一步
  19. 如果需要,可以输入规则的名称并记下转储的保存位置。 在需要时可以更改此位置。
  20. 选择下一步
  21. 选择“ 立即激活规则”,然后选择“ 完成”。

提示

可以使用步骤 13-15 中使用的相同方法添加多个转储目标,以创建多个应用程序池的转储。

此规则将创建 11 个转储文件。 前 10 个转储是“微型转储”,其大小很小。 最后一个转储是具有完整内存的转储,该转储要大得多。

一旦发生CPU 使用率过高的问题,需要停止 Perfmon 数据收集器集,使其不再收集数据。 为此,请右键单击“用户定义的”节点下列出的高 CPU 数据收集器集,然后选择“停止”。

数据分析

在发生 CPU 使用率过高事件之后,有两组数据可供查看:Perfmon 数据收集器集和内存转储。 让我们首先查看 Perfmon 数据。

分析性能数据

若要查看问题的 Perfmon 数据,请右键单击“用户定义的”节点下列出的高 CPU 数据收集器集,然后选择“最新报告”。 你将看到类似于以下屏幕截图的报告。

显示性能监视器窗口的屏幕截图。

第一件事是删除所有当前计数器,以便可以添加要审阅的显式计数器。 选择列表中的第一个计数器。 然后滚动到列表底部,然后在按住 SHIFT 键时选择最后一个计数器。 选择所有计数器后,按 Delete 键将其删除。

现在,使用以下步骤添加 Process / % Processor Time 计数器:

  1. 右键单击 Perfmon 右窗格中的任意位置,然后选择“ 添加计数器”。
  2. 展开 Process 对象。
  3. 从列表中选择%处理器时间
  4. <从实例列表中选择所有实例>
  5. 选择 添加
  6. 选择“确定”

现在,你将看到一个显示画面,其中显示了数据收集器集在运行期间,计算机上每个进程使用的处理器时间的图表。 查明哪个进程使用的 CPU 最多的最简单方法是启用 Perfmon 的突出显示功能。

为此,请选择列表中的第一个计数器,然后按 Ctrl + H。完成此操作后,所选过程将在图形上显示为粗体黑线。

使用键盘上的向下箭头在进程列表中向下移动,直到找到 CPU 使用率最高的进程。 在以下屏幕截图中,可以清楚地看到w3wp.exe进程正在使用计算机上的大量 CPU。 这证实了 IIS 应用程序池导致计算机上出现 CPU 利用率较高的问题。

显示性能监视器窗口的屏幕截图。Perfmon 显示 w 3 w p 可执行文件的 C P U 用法。

提示

Perfmon 对于确定应用程序中的性能问题非常有用。 Perfmon 日志中收集的数据可以显示正在执行的请求数量(使用 ASP.NET 和 ASP.NET 应用程序对象),还可以显示有关应用程序执行情况的其他重要性能数据。

若要从根本上解决导致高 CPU 使用率的问题,让我们回顾一下使用 DebugDiag 创建的转储。

使用 DebugDiag 进行转储分析

DebugDiag 可以通过执行自动转储分析来识别许多问题。 对于此特定问题,DebugDiag 的性能分析器非常适合帮助确定高 CPU 使用率问题的根本原因。 若要使用分析器,请执行以下步骤

  1. DebugDiag 中选择“高级分析 ”选项卡。
  2. 选择性能分析器
  3. 选择“ 添加数据文件”。
  4. 浏览到创建转储的位置。 默认情况下,这是 C:\Program Files\DebugDiag\Logs 文件夹的子文件夹。
  5. 选择其中一个转储,然后按 Ctrl + A 选择该文件夹中的所有转储。
  6. 选择打开
  7. 选择开始分析

DebugDiag 需要几分钟时间分析转储并提供分析。 完成分析后,会看到类似于下图所示的页面。

显示 Internet Explorer 的屏幕截图。将显示“调试诊断分析报表”页。

请注意,报告顶部会告知检测到高 CPU。 在右侧列中,你会看到建议,其中包括按平均 CPU 时间排列的前 7 个线程的链接。 选择该链接,你将看到有关这些顶级 CPU 使用者正在执行的操作的信息。 例如,以下屏幕截图显示了这些线程在我的应用程序中执行的操作。

显示浏览器中“Functions 统计信息”页的屏幕截图。

在此示例中, FastApp 应用程序中的default.aspx 页正在运行。 如果进一步查看调用堆栈(页面底部),可以看到此线程正在执行字符串串联。 (请注意对调用堆栈的调用 System.String.Concat 。如果分析其他顶级 CPU 线程,则会看到相同的模式。

下一步是在 FastApp 应用程序的default.aspx页中查看Page_Load事件。 这样做时,我发现了以下代码。

htmlTable += "<table>";
for (int x = 0; x < 5000; x++)
{
htmlTable += "<tr>" + "<td>" + "Cell A" + x.ToString() + "</td>";
    htmlTable += "<td>" + "Cell B" + x.ToString() + "</td>" + "</tr>";
}
htmlTable += "</table>";

这种代码肯定会导致 CPU 使用率过高。

结束语

使用 Perfmon 和 DebugDiag,可以轻松收集有助于确定应用程序池中 CPU 使用率过高的原因的数据。 如果无法使用这些技术找到根本原因,可以联系Microsoft支持人员获取进一步帮助。 Microsoft支持工程师可帮助你确定问题的原因。 通过在打开案例时准备好 Perfmon 数据和转储,可以大幅减少工程师为你提供帮助所需的时间。

其他资源