尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

.NET Linux 性能追踪实战:PerfCollect(LTTng)与 dotnet-trace(EventPipe)全流程指南

.NET Linux 性能追踪实战:PerfCollect(LTTng)与 dotnet-trace(EventPipe)全流程指南 .NET Linux 性能追踪实战PerfCollectLTTng与 dotnet-traceEventPipe全流程指南【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址: https://gitcode.com/GitHub_Trending/runtime6/runtime本文基于当前仓库 docs/project/linux-performance-tracing.md 编写系统讲解 .NETCoreCLR在 Linux 上排查性能问题时的两种追踪机制基于 LTTng 的PerfCollect适用于 .NET Core 2.1与基于EventPipe的dotnet-trace适用于 .NET Core 3.0。读者将掌握从环境准备、采集 trace、解析框架与原生符号到 Docker 容器内采集、事件过滤以及在 PerfView / SpeedScope 中查看结果的完整实战技能并能理解这两套机制在 CoreCLR 内部的实现原理。当 .NET 应用在 Linux 上出现 CPU 飙高、GC 异常或 JIT 行为诡异等性能问题时首要任务是在问题发生时抓取足够细粒度的事件数据。CoreCLR 为此提供了两套并行的追踪机制本指南将带领你完整走通从采集到分析的每一步。一、两种追踪机制PerfCollectLTTng与 dotnet-traceEventPipe怎么选CoreCLR 在 Linux 上支持两种不同的 .NET 应用追踪机制分别对应两套 .NET 团队自研的工具维度PerfCollect基于 LTTngdotnet-trace基于 EventPipe底层机制LTTngLinux 内核级追踪框架EventPipe运行时内置跨平台追踪管线平台支持仅限 Linux依赖内核框架全平台一致Windows / macOS / Linux调用栈能力借助perf可拿到原生调用栈native callstacks只能给出托管调用栈managed callstack采集范围机器级machine-wide可同时捕获同机多个进程的事件绑定单个运行时实例specific to a single runtime instance启动时机可在进程启动之前开始采集只能在进程启动、且运行时已建立内部数据结构支持 attach 之后附加版本要求.NET Core 2.1 或更高.NET Core 3.0 或更高选择建议如果问题涉及原生层如 libcoreclr.so 内部、P/Invoke 边界或需要同时观察多个进程优先 PerfCollect如果追求跨平台一致的采集体验、只关心托管层行为dotnet-trace 更轻量、门槛更低。二、LTTng 与 PerfCollect.NET Core 2.1 或更高2.1 所需工具perfcollect一个 Bash 脚本自动化完成数据采集与后处理。可通过aka.ms/perfcollect获取见下文下载命令。PerfViewWindows 上的性能分析工具可以分析 PerfCollect 采集到的 trace 文件通常配合 Windows 机器使用。可通过aka.ms/perfview获取。2.2 准备采集机器按以下步骤把机器准备好即可开始采集性能 trace下载 PerfCollect 脚本curl -OL https://aka.ms/perfcollect赋予执行权限chmod x perfcollect安装追踪前置依赖——这些是真正的追踪库详见文末「额外信息」章节的前置依赖说明sudo ./perfcollect install2.3 采集 Trace建议开两个 Shell 窗口一个用于控制追踪记为[Trace]一个用于运行应用记为[App]。[App]配置应用 Shell——为 CoreCLR 开启追踪所需的配置export DOTNET_PerfMapEnabled1 export DOTNET_EnableEventLog1注意DOTNET_PerfMapEnabled会让 .NET 运行时把托管代码的符号信息perf map写入磁盘。取决于磁盘性能与应用中托管代码量这会带来可观的开销。[Trace]开始采集sudo ./perfcollect collect sampleTrace预期输出Collection started. Press CTRLC to stop.[App]运行应用让问题场景持续足够时间以被捕获。通常不需要很久——例如 CPU 问题调查5~10 秒的高 CPU 状态一般就足够了dotnet run[Trace]按CTRLC停止采集^C ...STOPPED. Starting post-processing. This may take some time. Generating native image symbol files ...SKIPPED Saving native symbols ...FINISHED Exporting perf.data file ...FINISHED Compressing trace files ...FINISHED Cleaning up artifacts ...FINISHED Trace saved to sampleTrace.trace.zip压缩后的 trace 文件保存在当前工作目录。2.4 解析框架符号Framework Symbols框架符号需要在采集时手工生成它与应用级符号不同框架是预编译的precompiled而应用是即时编译JIT的。对于预编译为原生代码的框架代码需要特殊的工具crossgen才能生成从原生代码到方法名的映射。PerfCollect 能替你处理大部分细节但它需要找到 crossgen 工具而 crossgen默认并不包含在标准 .NET 发行版中。如果找不到PerfCollect 会给出警告并引导你阅读本指南。解决方法获取与当前所用运行时完全匹配的 crossgen 版本将其放到 .NET 运行时 DLL如libcoreclr.so同一目录下PerfCollect 就能找到它并把框架符号写入 trace。获取正确版本 crossgen 的途径之一是借助自包含发布mkdir helloWorld cd helloWorld dotnet new console dotnet publish --self-contained -r linux-x64这会创建一个自包含self-contained应用。其副产物是dotnet工具会下载名为runtime.linux-x64.microsoft.netcore.app的 NuGet 包放在~/.nuget/packages/runtime.linux-x64.microsoft.netcore.app/VERSION/目录下VERSION 即运行时版本号例如2.1.0其中的tools目录里就有你需要的 crossgen。从 .NET Core 3.0 起包位置变为~/.nuget/packages/microsoft.netcore.app.runtime.linux-x64/VERSION。微妙之处若机器上安装了多个版本的 .NET 运行时上述步骤默认使用最新版。只要你的应用也使用最新版通常是这种情况这些步骤就无需修改。crossgen 需要放到应用实际使用的运行时旁边。典型情况下应用使用共享运行时位于/usr/share/dotnet/shared/Microsoft.NETCore.App/VERSIONVERSION 为运行时版本号。该目录是共享位置需要超级用户权限才能修改。若 VERSION 为 2.1.0sudo bash cp ~/.nuget/packages/runtime.linux-x64.microsoft.netcore.app/2.1.0/tools/crossgen /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0完成之后PerfCollect 会借助 crossgen 把框架符号纳入 trace原先的警告也会消失。该操作每台机器只需做一次直到升级运行时。替代方案关闭预编译代码的使用如果无法修改 .NET 运行时无法加入 crossgen或上述流程失败还有另一条获得框架符号的路径让运行时不使用预编译的框架代码改为即时编译从而不再需要 crossgen。代价是应用启动时间增加约 1~2 秒通常可以接受。在原来设置符号相关的环境变量基础上只需再加一个export DOTNET_ReadyToRun0此改动之后即可获得全部 .NET 代码的符号。源码佐证DOTNET_ReadyToRun0之所以有效与 perfmap.cpp 中的实现逻辑直接相关——该文件注释明确写到 PerfMap does not log R2R methodsPerfMap 不记录 ReadyToRun 预编译方法只有发出 jitdump 时才遍历ReadyToRunInfo::MethodIterator处理预编译方法。也就是说默认采集perf map模式下预编译代码没有符号关闭 ReadyToRun 后所有代码走 JIT 路径符号自然齐备。2.5 获取原生运行时符号大多数时候你关注的是自己的代码PerfCollect 默认即可解析。有时你可能想看 .NET 框架 DLL 内部上一节的主题或原生运行时 DLL典型如libcoreclr.so内部的行为。PerfCollect 在转换数据时会解析这些原生符号但前提是这些原生 DLL 的符号文件存在且位于对应库旁边。全局工具dotnet-symbol可以完成此任务分两步安装 dotnet-symboldotnet tool install -g dotnet-symbol下载符号——为所有原生库包括 .NET 运行时/框架以及任何其他已安装的框架如 ASP.NET下载符号并放到它们旁边sudo dotnet symbol --recurse-subdirectories --symbols /usr/share/dotnet/*.so该工具主要为调试设计但同样适用于 PerfCollect 采集。2.6 在 Docker 容器中采集PerfCollect 可以采集 Docker 容器内运行应用的数据。关键认知是采集 trace 需要提升权限因为 Docker 默认的 seccomp profile 会拦截所需的系统调用perf_events_open。要在容器内按本指南采集需要在容器中启动一个privileged特权的 Shelldocker exec -it --privileged container_name /artifacts/bash容器内托管的应用程序本身无需特权但这个新 Shell 是特权的拥有采集 trace 数据所需的全部权限。之后只需使用这个特权 Shell 按照上文「采集 Trace」的步骤操作即可。2.7 过滤Filtering在 Windows 上过滤是通过EventSource类提供的最新机制实现的在 Linux 上这些机制尚不可用取而代之的是两个仅存在于 Linux 的环境变量用于做基础过滤DOTNET_EventSourceFilter—— 按名称过滤事件源event sourcesDOTNET_EventNameFilter—— 按名称过滤事件events设置其中一个或两个变量后只会采集名称包含你指定子串的事件。字符串匹配不区分大小写。2.8 查看 TraceTrace 最适合在 Windows 上用 PerfView 查看.NET 团队正在评估将 PerfView 的分析部分移植到 Linux以实现在 Linux 上完成整个调查流程。打开 Trace 文件把trace.zip文件从 Linux 复制到 Windows 机器。通过aka.ms/perfview下载 PerfView。运行 PerfView.exePerfView.exe path to trace.zip file选择合适的视图PerfView 会根据 trace 文件包含的数据显示支持的视图列表CPU 调查选择CPU stacks。非常详细的 GC 信息选择GCStats。按进程/模块/方法查看 JIT 信息选择JITStats。若没有所需信息的专用视图可在原始事件视图中查找事件选择Events。视图解读的更多细节可查看视图内的帮助链接或在 PerfView 主窗口选择Help - Users Guide。2.9 额外信息前置依赖PrerequisitesPerfCollect 会提醒用户任何未安装的前置依赖并提供安装。可通过如下命令自动安装sudo ./perfcollect install当前前置依赖包括perf即 perf_eventLinux Performance Events 子系统及其配套的用户态采集/查看应用。perf 属于 Linux 内核源码的一部分但通常不会默认安装。LTTng全称 Linux Tracing Toolkit Next GenerationLinux 下一代追踪工具包用于捕获 CoreCLR 运行时发出的事件数据。这些数据随后用于分析 GC、JIT、线程池等运行时组件的行为。三、EventPipe 与 dotnet-trace.NET Core 3.0 或更高3.1 简介EventPipe是 .NET Core 3.0 起内置到运行时中的全新跨平台追踪机制在所有受支持平台Windows、macOS、Linux上行为完全一致。其底层实现位于 CoreCLR 运行时内部——例如 eventpipeinternal.cpp 中的EventPipeInternal_Enable、EventPipeInternal_Disable、EventPipeInternal_GetSessionInfo等 QCALL 接口通过这些接口把托管诊断层与原生 EventPipe 会话、Provider、序列化格式连接起来。基于它.NET 团队构建了各种诊断工具。dotnet-trace就是一款基于 EventPipe 对 .NET 应用进行追踪的 dotnet CLI 工具。3.2 安装 dotnet-trace通过 dotnet CLI 即可安装dotnet tool install --global dotnet-trace3.3 采集 Trace先查看当前机器上有哪些 .NET 进程可供采集获取进程 ID即 PIDdotnet-trace ps拿到目标进程 PID 后即可开始追踪dotnet-trace collect --process-id PID3.4 查看 Trace在Windows上结果 trace 可用 PerfView 查看。在Linux/macOS上采集时传入--format speedscope参数将 trace 转换为 speedscope 格式即可在 SpeedScope 中查看dotnet-trace collect --process-id PID --format speedscopeSpeedScope 是 Web 端即可打开的火焰图查看器非常适合快速浏览 CPU 采样结果。关于 dotnet-trace 更完整的使用方法如按 Provider 过滤、控制采集时长、输出文件命名等可查阅 .NET diagnostics 仓库中对应的 dotnet-trace 使用文档。四、结语需要原生调用栈、机器级多进程、进程启动前开始采集或运行环境为 .NET Core 2.1~2.2 时选择PerfCollectLTTng记得通过DOTNET_PerfMapEnabled/DOTNET_EnableEventLog开启运行时符号输出必要时借助 crossgen 或DOTNET_ReadyToRun0补齐框架符号用 dotnet-symbol 补齐原生符号。需要跨平台一致、轻量快速的托管层追踪或运行环境为 .NET Core 3.0 时选择dotnet-traceEventPipe配合--format speedscope可以在 Linux/macOS 上直接完成火焰图分析。在 Docker 等受限容器中采集时务必先以--privileged启动 Shell绕过 seccomp 对perf_events_open的拦截。把两套工具组合进日常性能调查流程配合 PerfView 的 CPU stacks / GCStats / JITStats 视图即可在 Linux 上对 .NET 应用做体系化的性能剖析。深入理解其底层机制PerfMap 与 EventPipe还能帮助你在符号缺失、过滤失效等异常场景下快速定位根因。【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址: https://gitcode.com/GitHub_Trending/runtime6/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表