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