编者按:即使.NET Core3.1.5已经发布,在进行.NET Core的性能诊断时,我们有时依然不知该从何处下手,那这篇介绍.NET Core3.0中引入的诊断工具,或许能为我们提供参考。
在.NET Core 3.0中,我们引入了一套工具,这些工具利用了.NET运行时中的新功能,使诊断和解决性能问题变得更加容易。
这些运行时功能可帮助您回答一些常见的诊断问题:
我的应用程序健康吗?
为什么我的应用程序有异常行为?
为什么我的应用程序崩溃了?
我的应用程序健康吗?
通常,应用程序可能会慢慢开始泄漏内存,并最终导致内存不足异常。在其他时候,某些有问题的代码路径可能会导致CPU使用率激增。这些只是您可以通过指标主动识别的一些问题类别。
指标
指标表示一段时间内的数据量度。指标(或时间序列)数据使您可以从高层次观察系统状态。与Windows上的.NET Framework不同,.NET Core不会发出性能计数器。相反,我们引入了一种通过EventCounter API 在.NET Core中发出指标的新方法。
EventCounters提供了Windows性能计数器的改进,因为这些计数器现在可在支持.NET Core的所有操作系统上使用。此外,与perf计数器不同,它们还可以在低特权环境(例如xcopy部署)中使用。不幸的是,由于缺少诸如性能监视器(perfmon)之类的工具,因此很难实时使用这些指标。
dotnet-counters
在3.0-preview5中,我们引入了一个新的命令行工具,用于实时观察.NET Core应用程序发出的指标。
您可以通过运行以下命令来安装此.NET全局工具
dotnet tool install --global dotnet-counters --version 1.0.3-preview5.19251.2
在下面的示例中,当我们将负载生成器指向Web应用程序时,我们看到应用程序的CPU利用率和工作集内存急剧上升。
有关如何使用此工具的详细说明,请参阅dotnet-counters自述文件。对于已知的限制,请查看GitHub上的未解决问题。
dotnet-counters
为什么我的应用程序有异常行为?
虽然指标可以帮助识别异常行为的发生,但它们几乎无法提供问题的可见性。要回答为什么您的应用程序具有异常行为的问题,您需要通过跟踪收集其他信息。例如,通过跟踪收集的CPU配置文件可以帮助您识别代码中的热路径。
追踪
跟踪是离散事件的不加时间戳的记录。跟踪包含本地上下文,可让您更好地推断系统的命运。传统上,.NET Framework(以及ASP.NET等框架)通过Windows事件跟踪(ETW)发出有关其内部的诊断跟踪。在.NET Core中,这些跟踪被写入Windows上的ETW和Linux上的LTTng。
dotnet-trace
在3.0-preview5中,每个.NET Core应用程序都会打开一个双工管道EventPipe
(该管道可以在其上发出事件)(在* nix上是Unix域套接字/在Windows上是一个命名管道)。当我们仍在研究控制器协议时,请实现此协议的预览版。dotnet-trace
您可以通过运行以下命令来安装此.NET全局工具
dotnet tool install --global dotnet-trace--version 1.0.3-preview5.19251.2
在上面的示例中,我dotnet trace
使用默认配置文件运行,该配置文件启用了CPU事件探查器事件和.NET运行时事件。
除了默认事件之外,您还可以根据要尝试执行的调查来启用其他提供程序。
运行后dotnet trace
,将显示一个.netperf文件。该文件包含运行时事件和可以在perfview中显示的示例 CPU堆栈。Visual Studio的下一个更新(16.1)也将添加对可视化这些跟踪的支持。
您可以通过运行以下命令来转换现有跟踪
dotnet trace convert <input-netperf-file>
下图显示了冰柱图,可视化了我们刚刚在Speedscope中捕获的轨迹。
为什么我的应用程序崩溃了?
在某些情况下,仅通过跟踪过程就不可能确定导致异常行为的原因。如果流程崩溃或我们可能需要更多信息(例如访问整个流程堆)的情况,则流程转储可能更适合分析。
转储分析
转储是通常在进程意外终止时捕获的进程的工作虚拟内存状态的记录。诊断核心转储通常用于确定应用程序崩溃或意外行为的原因。
传统上,您在应用程序崩溃时依靠操作系统来捕获转储(例如Windows错误报告),或者在满足某些触发条件时使用procdump之类的工具来捕获转储。
迄今为止,在Linux上使用.NET捕获转储的挑战是使用NET捕获转储,gcore
否则调试器会导致极大的转储,因为现有工具不知道在.NET Core进程中要修剪哪些虚拟内存页。
此外,即使您已经收集了这些转储,也仍然需要分析调试器,因为它需要获取调试器并将其配置为加载sos
(.NET的调试器扩展),这具有挑战性。
dotnet-dump
3.0.0-preview5,我们引入了一个新工具,使您可以捕获和分析Windows和Linux上的进程转储。
dotnet-dump
仍在积极开发中,下表显示了哪些操作系统当前支持哪些功能。
视窗 | OS X | 的Linux | |
收集 | ✅ | ❌ | ✅ |
分析 | ❌ | ❌ | ✅ |
您可以通过运行以下命令来安装此.NET全局工具
dotnet tool install --global dotnet-dump --version 1.0.3-preview5.19251.2
安装完成后,您可以通过运行以下命令来捕获进程转储dotnet dump
sudo $HOME/.dotnet/tools/dotnet-dump collect -p
在Linux上,可以通过运行以下命令加载结果转储来分析结果转储
dotnet dump analyze <dump-name>
在下面的示例中,我尝试通过遍历堆来确定崩溃转储的ASP.NET Core宿主环境。
有关如何使用此工具的详细说明,请参阅dotnet-dump自述文件。对于已知的dotnet-dump限制,请查看GitHub上的未解决问题。