排查 IIS 应用程序池中 CPU 使用率过高的问题
适用于: Internet 信息服务
此疑难解答将帮助你确定 Internet 信息服务 (IIS) 应用程序池中 CPU 持续高的原因。 请务必记住,当 Web 应用程序提供请求时,CPU 使用率增加是正常的。 但是,如果你一直看到 CPU 长时间保持在 80% 或更高) 区域中的较高水平 (,应用程序的性能将受到影响。 因此,请务必了解 CPU 持续高企的原因,以便尽可能对其进行处理和更正。
应用场景
IIS 中的应用程序池遇到超过 90% 的长时间高 CPU。 测试应用程序时,不会遇到任何问题。 但是,一旦应用程序遇到实际用户负载,CPU 就会攀升至较高百分比并保持不变。 若要恢复,必须重启应用程序池,但执行此操作后,CPU 会再次攀升到较高级别。
工具
- 调试诊断 (Diag)
- 性能监视器 (Perfmon)
数据收集
遇到 CPU 使用率过高问题时,首先应确定占用 CPU 的进程。 可以使用任务管理器中的“ 进程 ”选项卡执行此操作。 请确保选中“ 显示所有用户的进程 ”复选框。 下图显示了此框已选中,并显示了 w3wp.exe
托管 IIS 应用程序池的进程 (进程,) 占用大量 CPU。
还可以使用 性能监视器 来确定使用 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 使用率过高问题,请执行以下步骤。
- 从 Windows 控制面板打开管理工具。
- 双击性能监视器。
- 展开“ 数据收集器集” 节点。
- 右键单击“ 用户定义的 ”,然后选择“ 新建 ->数据收集器集”。
- 输入 “高 CPU ”作为数据收集器集的名称。
- 选择“ 手动创建” (“”高级) ”。
- 选择“下一步”。
- 选择“ 创建数据日志”。
- 选中“ 性能计数器 ”复选框。
- 选择“下一步”。
- 选择“添加”。 如果应用程序不是 ASP.NET 应用程序,请继续执行步骤 19。
- 滚动到计数器列表的顶部,然后选择“ .NET CLR 内存”。
- 在实例列表中,选择 <所有实例>。
- 选择“ 添加” ,将计数器添加到添加的计数器列表中。
- 从计数器列表中选择 “ASP.NET ”,然后选择“ 添加”。
- 从计数器列表中选择 “ASP.NET 应用程序 ”。
- <从实例>列表中选择所有实例。
- 选择“添加”。
- 从计数器列表中展开 “进程 ”。 (请确保展开 “进程” 而不是 “Processor”。)
- 从“进程”对象中选择“处理器时间百分比”。
- <从实例>列表中选择所有实例。
- 选择“添加”。
- 从计数器列表中展开 “线程 ”。
- 从 Thread 对象中选择“处理器时间百分比”。
- <从实例>列表中选择所有实例。
- 选择“添加”。
- 从实例列表中选择“ ID 线程 ”。
- 选择“添加”。
现在,对话框应如下图所示。
选择 “确定” ->“下一步”。 记下数据收集器集的保存位置。 (如果需要,可以更改此位置。) 然后选择“ 完成”。
数据收集器集尚未运行。 若要启动它,请右键单击“用户定义的”节点下的“高 CPU”,然后从菜单中选择“启动”。
创建调试诊断规则
当出现高 CPU 情况时,收集用户模式进程转储的最简单方法是使用调试诊断。
下载 DebugDiag,在服务器上安装并运行它。 (安装后的 “开始 ”菜单上会显示它。) 运行 DebugDiag 时,将显示“ 选择规则类型 ”对话框。 按照以下步骤为应用程序池创建崩溃规则:
- 选择“ 性能 ”->“下一步”。
- 选择“ 性能计数器 ”->“下一步”。
- 选择 “添加性能触发器”。
- 展开 “处理器 ” (而不是“进程) ”对象,然后选择“ 处理器时间百分比”。 请注意,如果你使用的是 Windows Server 2008 R2 并且你拥有 64 个以上的处理器,请选择 “处理器信息” 对象而不是 Processor 对象。
- 在实例列表中,选择“ _Total”。
- 选择 “添加 ”->“确定”。
- 选择新添加的触发器,然后选择 “编辑阈值”。
- 在下拉列表中选择“ 上图 ”。
- 将阈值更改为 80。
- 输入 20 代表秒数。 (可以根据需要调整此值,但请注意不要指定少量秒,以防止假触发器。)
- 选择“确定”。
- 选择 下一步。
- 选择“ 添加转储目标”。
- 从下拉列表中选择“ Web 应用程序池 ”。
- 从应用池列表中选择应用程序池。
- 选择“确定”。
- 选择 下一步。
- 再次选择“ 下一步 ”。
- 如果需要,请输入规则的名称,并记下转储的保存位置。 如果需要,可以更改此位置。
- 选择“下一步”。
- 选择“ 立即激活规则”,然后选择“ 完成”。
提示
可以使用步骤 13-15 中使用的相同技术添加多个转储目标,从而创建多个应用程序池的转储。
此规则将创建 11 个转储文件。 前 10 个将是“微型转储”,其大小相当小。 最终转储将是具有完整内存的转储,该转储会更大。
出现 CPU 使用率过高问题后,需要阻止 Perfmon 数据收集器集收集数据。 为此,请右键单击“用户定义”节点下列出的“高 CPU 数据收集器集”,然后选择“停止”。
数据分析
CPU 高事件后,你将有两组数据要查看:Perfmon 数据收集器集和内存转储。 让我们首先查看 Perfmon 数据。
分析性能数据
若要查看问题的 Perfmon 数据,请右键单击“用户定义”节点下列出的“高 CPU 数据收集器集”,然后选择“最新报告”。 你将看到类似于以下屏幕截图的报告。
第一件事是删除所有当前计数器,以便可以添加要查看的显式计数器。 选择列表中的第一个计数器。 然后滚动到列表底部,按住 SHIFT 键的同时选择最后一个计数器。 选择所有计数器后,按 Delete 键将其删除。
现在,使用以下步骤添加 进程 / 百分比处理器时间计数器 :
- 右键单击 Perfmon 右窗格中的任意位置,然后选择“ 添加计数器”。
- 展开 Process 对象。
- 从列表中选择“ 处理器时间百分比 ”。
- <从实例>列表中选择所有实例。
- 选择“添加”。
- 选择“确定”。
现在,你将有一个显示计算机上每个进程在数据收集器集运行时使用的处理器时间的图形。 要隔离哪个进程使用的是最高 CPU 级别,最简单的方法是启用 Perfmon 的突出显示功能。
为此,请选择列表中的第一个计数器,然后按 Ctrl + H。完成此操作后,所选进程将在图形上显示为加粗的黑线。
使用键盘上的向下箭头在进程列表中向下移动,直到找到显示 CPU 使用率最高的进程。 在以下屏幕截图中,可以清楚地看到,w3wp.exe 进程在计算机上使用了大量 CPU。 这确认 IIS 应用程序池导致计算机上的 CPU 使用率过高。
提示
Perfmon 在确定应用程序中的性能问题时非常有用。 Perfmon 日志中收集的数据可以显示使用 ASP.NET 和 ASP.NET Applications 对象) 执行 (的请求数,还可以显示有关应用程序执行方式的其他重要性能数据。
若要了解导致 CPU 使用率过高问题的根本原因,请查看使用 DebugDiag 创建的转储。
使用 DebugDiag 进行转储分析
DebugDiag 能够通过执行自动转储分析来识别许多问题。 对于此特定问题,DebugDiag 的性能分析器非常适合帮助确定 CPU 使用率过高问题的根本原因。 若要使用分析器,请执行以下步骤
- 在 DebugDiag 中选择“ 高级分析 ”选项卡。
- 选择 “性能分析器”。
- 选择 “添加数据文件”。
- 浏览器到创建转储的位置。 默认情况下,这是 C:\Program Files\DebugDiag\Logs 文件夹的子文件夹。
- 选择其中一个转储,然后按 Ctrl + A 选择该文件夹中的所有转储。
- 选择 “打开”。
- 选择“ 开始分析”。
DebugDiag 需要几分钟时间来分析转储并提供分析。 完成分析后,会看到类似于下图所示的页面。
请注意,报表顶部指示检测到 CPU 使用率过高。 在右侧列中,你将看到建议,其中包括按平均 CPU 时间指向前 7 个线程的链接。 选择该链接,你将看到有关这些顶级 CPU 使用者正在执行的操作的信息。 例如,以下屏幕截图显示了这些线程在我的应用程序中执行的操作。
在此示例中,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 数据和转储,可以大大减少工程师为你提供帮助所需的时间。