ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Aspire CLI 启动性能剖析实战:--capture-profile 自画像采集与 OTEL 追踪导出

Aspire CLI 启动性能剖析实战:--capture-profile 自画像采集与 OTEL 追踪导出 Aspire CLI 启动性能剖析实战--capture-profile 自画像采集与 OTEL 追踪导出【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspireAspire 提供了内建的启动性能剖析机制通过隐藏的--capture-profile标志CLI 会临时拉起一个私有的 Dashboard 采集器为当前命令及其子 AppHost 进程启用仅用于剖析的 OpenTelemetry 埋点并在启动完成后自动导出一份 OTLP JSON 追踪档案。读完本文你将掌握如何用该流程测量aspire run/aspire start的启动耗时、如何解读导出的 span 结构、如何为改动前后的性能做可比对照以及遇到问题时如何依据源码定位根因。剖析模型与上报遥测完全隔离的 opt-in 机制Aspire 的剖析profiling是显式可选的并且与正常上报的遥测reported telemetry严格分离通过环境变量ASPIRE_PROFILING_ENABLEDtrue或1启用剖析。CLI 侧剖析 span 使用Aspire.Cli.ProfilingActivitySource定义见 ProfilingTelemetry.cs。Hosting 侧剖析 span 使用Aspire.Hosting.ProfilingActivitySource。当 DCP 进程发出启动遥测时其 span 归属dcp.startupinstrumentation scope。上报遥测中不得携带剖析会话 IDaspire.profiling.session_id、高基数剖析标签或剖析 span。从源码结构看这一隔离设计在多处得到落实。Program.cs 在构建 DI 容器之前就用一个引导式命令解析器解析--capture-profile相关参数并通过 ProfileCaptureEnvironment.Apply 修改进程环境变量——因为TelemetryManager在 DI 启动时就会读取 OTEL 配置等到 System.CommandLine 绑定参数就太晚了。该环境同时设置环境变量作用ASPIRE_PROFILING_ENABLEDtrue开启剖析常量定义见 KnownConfigNames.csASPIRE_PROFILING_SESSION_IDsession本次采集的会话 ID用于关联 CLI/Hosting/DCP 三类 span旧版兼容项ASPIRE_STARTUP_PROFILING_ENABLED、ASPIRE_STARTUP_OPERATION_ID兼容旧命名的 AppHostOTEL_EXPORTER_OTLP_ENDPOINT、OTEL_EXPORTER_OTLP_PROTOCOLgrpc将 span 导出指向私有采集器的 gRPC 端点OTEL_BSP_SCHEDULE_DELAY1000批量导出器调度延迟 1 秒给子进程 span 留出到达窗口此外上报遥测的 opt-out 开关被置为启用确保剖析数据不会经由正常上报通道外泄。前置条件构建支持 --capture-profile 的 CLI需要使用包含--capture-profile的 Aspire CLI 构建。从仓库检出目录构建./restore.sh ./dotnet.sh build src/Aspire.Cli/Aspire.Cli.csproj /p:SkipNativeBuildtrueDashboard 二进制aspire-managed的查找顺序见 ProfileCaptureService.cs显式覆盖ASPIRE_DASHBOARD_PATH较旧的 hosting/DCP 覆盖名需直接指向可执行文件或ASPIRE_MANAGED_PATH既可指向可执行文件本身也可指向 bundle 布局中的 managed 目录见 ResolveManagedPathOverride。bundle 布局已安装/打包的 CLI 从 bundle 中提取。仓库本地开发构建当ASPIRE_REPO_ROOT指向检出目录时固定查找artifacts/bin/Aspire.Managed/Debug/net10.0/下的可执行文件ResolveRepoLocalManagedPath。ASPIRE_REPO_ROOT是开发构建的逃生通道只有显式设置它仓库本地构建才会被发现避免已安装 CLI 在剖析无关应用时误绑定到附近的检出目录。快速开始一次命令完成采集与导出采集 AppHost 启动并自动退出./dotnet.sh exec artifacts/bin/Aspire.Cli/Debug/net10.0/aspire.dll run \ --project tests/TestingAppHost1/TestingAppHost1.AppHost/TestingAppHost1.AppHost.csproj \ --capture-profile \ --capture-profile-output artifacts/tmp/startup-profile/profile.zip \ --non-interactive采集任意其他 Aspire 命令aspire ls \ --capture-profile \ --capture-profile-output artifacts/tmp/startup-profile/ls-profile.zip \ --non-interactive省略--capture-profile-output时CLI 会在当前工作目录写入aspire-profile-timestamp-session.zip默认文件名格式由 CreateDefaultOutputFileName 生成。对于长生命周期的run和start命令CLI 会在启动完成后自动退出并等待剖析数据稳定settle后才写出导出文件。整个采集结束后进程以被包装命令的退出码返回只有当原命令成功而导出失败时退出码才会被改写为 dashboard 失败码Program.cs。自画像选项详解选项说明--capture-profile隐藏的递归根选项为任意 Aspire 命令启用自画像采集--capture-profile-output PATH输出 zip 路径相对路径以当前工作目录为根--capture-profile-delay SECONDS长生命周期run/start命令停止前的可选预热延迟默认 5 秒确保 AppHost 侧 span 在关闭前有时间刷出。若想故意让启动后的资源活动进入采集可增大该值这些选项在 RootCommand.cs 中声明默认延迟常量DefaultCaptureProfileDelaySeconds 5。参数解析与端口分配的细节值得注意ProfileCaptureOptions.TryCreate会话 ID每次采集生成Guid.NewGuid().ToString(N)即 32 位十六进制串用于把 CLI、Hosting、DCP 三方 span 归入同一关联追踪。端口分配为 dashboard HTTP、OTLP gRPC、OTLP HTTP 各分配一个回环loopback临时端口。这意味着并行采集天然支持——每个--capture-profile进程拥有独立的采集器端口和会话 ID互不冲突。--分隔符语义引导解析器使用TreatUnmatchedTokensAsErrors false--之后的参数属于被包装的命令/AppHost不属于 Aspire 本身例如aspire run --capture-profile -- --capture-profile不会被误解析。输出路径的目录语义如果传入的路径已存在为目录、或以目录分隔符结尾则在其中生成默认档案名不存在的普通路径则按文件路径保留。采集流程的源码级剖析理解采集流程的内部时序有助于解释各类采集不完整现象。核心实现在 ProfileCaptureService.cs关键时序参数常量值含义s_dashboardStartTimeout90 秒等待私有 dashboard 的 Kestrel 开始接受请求的上限s_profileDataTimeout10 秒剖析数据稳定轮询的上限s_pollInterval250 毫秒轮询间隔ProfileDataQuietPolls8 次连续 8 次约 2 秒span 数量不变即判定数据已稳定s_dashboardDisposeTimeout5 秒释放阶段等待 dashboard 进程退出的上限流程可归纳为五步启动私有采集器直接拉起aspire-managed并传入dashboard子命令及--urls、OTLP gRPC/HTTP 端点、允许匿名访问与启用 API 等参数而不是回调aspire dashboard run——通过被剖析的 CLI 自身再调一次会递归应用--capture-profile把采集器自身也测进结果里源码注释。采集器进程还绑定在 Windows 的 kill-on-close 作业上作为跨平台看门狗之外的操作系统级兜底。防止采集器自我剖析CreateDashboardEnvironment 显式清空ASPIRE_PROFILING_ENABLED、会话 ID 和OTEL_EXPORTER_OTLP_*等变量确保采集器不会把自己或自己的导出混入被测数据。等待就绪轮询采集器的根 HTTP 端点而非仅等进程启动并监视进程退出任务让启动失败表现为明确的 dashboard 错误而不是笼统的连接超时。等待 span 稳定轮询 dashboard 的遥测 traces API只统计携带本次会话 ID 的 span——CLI/Hosting span 在 span 属性上带aspire.profiling.session_idDCP 拥有自己的剖析命名空间会在 resource 属性上带dcp.profiling.session_idCountSessionSpans。计数连续 8 次约 2 秒不变即视为稳定这样可以让子 AppHost 的批量导出器延迟刷出OTEL_BSP_SCHEDULE_DELAY1000的 span 来得及到达。导出并清理将 trace 数据写入导出 ziparchive.Traces[profile]显示完成消息随后Kill(entireProcessTree: true)终止采集器并带超时等待其退出。aspire run/aspire start在启动完成回调处读取CaptureProfileOption与延迟值在启动完成后按延迟窗口自动走退出路径见 RunCommand.cs随后 CLI 主流程执行ForceFlushProfilingAsync()再导出保证 CLI 自身最后时刻的 span 也已到达采集器。输出产物与验证方法采集写出的 dashboard 导出 zip 包含路径说明traces/profile.json来自私有 dashboard 采集器的 OTLP JSON trace 导出查看导出内容unzip -l artifacts/tmp/startup-profile/profile.zip tmpdir$(mktemp -d) unzip -q artifacts/tmp/startup-profile/profile.zip -d $tmpdir jq -r .resourceSpans[]?.scopeSpans[]?.scope.name $tmpdir/traces/profile.json | sort | uniq -c jq -r .resourceSpans[]?.scopeSpans[]?.spans[]?.name $tmpdir/traces/profile.json | sort | uniq -c预期的启动采集应包含Aspire.Cli.Profilingspan如aspire/cli/command、aspire/cli/run、dotnet 进程 span、backchannel 连接 span、dashboard URL 获取等。Aspire.Hosting.Profilingspan如 DCP model 工作、资源创建、资源等待、DCP 资源观测。dcp.startupspan当 DCP 进程发出启动遥测、且场景配置要求其存在时。会话 ID 的关联验证也可以直接用 jqspan 级属性形如{key:aspire.profiling.session_id,value:{stringValue:session}}DCP 侧在 resource 属性上。改动前后对比与并行采集推荐为基线和特性分支分别使用独立 worktree避免在脏工作树上切换分支干扰测量# 基线 worktree aspire run --project path/to/AppHost.csproj \ --capture-profile \ --capture-profile-output artifacts/tmp/startup-profile-baseline/profile.zip \ --non-interactive # 特性 worktree aspire run --project path/to/AppHost.csproj \ --capture-profile \ --capture-profile-output artifacts/tmp/startup-profile-feature/profile.zip \ --non-interactive对比traces/profile.json中 span 名称、持续时间、操作 ID、进程 ID、事件以及 trace 关联关系。若要做统计上有意义的墙钟时间wall-clock对比需手动多轮运行并保持环境稳定——自画像采集流程产出的是工件本身不是统计基准测试运行器。并行采集受支持因为每个进程分配独立的采集器端口和会话 ID但必须使用不同的--capture-profile-output路径。需要留意如果被剖析 AppHost 的启动 profile 固定了 dashboard、resource-service 或应用端口这些 AppHost 端口在并行 worktree 之间仍可能冲突此时应使用隔离/随机化 profile或调整 AppHost 端口。埋点设计指引为启动路径新增剖析埋点时保持剖析 API 粗粒度且剖析专用将原始Activity、活动名、标签名和事件名集中到所属区域的剖析遥测类型中Aspire.Cli.Profiling或Aspire.Hosting.Profiling。不要为每个标签暴露一个公开/内部方法优先提供操作/结果级方法接受一个阶段的数据并在内部批量设置多个标签/事件。好的 API 形态示例以命令、项目、工作目录和选项启动 dotnet 进程 span用 started/进程 ID 记录进程启动结果用退出码和输出条数记录进程完成以操作/资源类型启动 Kubernetes API span把重试细节记录为单个事件方法。调用方应描述正在剖析什么操作而不是知道标签/事件名。除非能确定当前活动就是剖析活动、或剖析已显式包装了它否则不要向Activity.Current添加剖析标签/事件。高基数数据不得进入上报遥测。常见问题排查现象原因解决The CLI bundle layout was found, but the dashboard binary (aspire-managed) is missing.CLI 找不到 bundle 内、仓库本地或覆盖路径上的 dashboard 二进制构建仓库本地 CLI、改用已安装/打包 CLI、将ASPIRE_REPO_ROOT指向检出目录或用ASPIRE_DASHBOARD_PATH/ASPIRE_MANAGED_PATH指定自定义 managed dashboard 构建导出中有 CLI span 但没有 Hosting spanAppHost 没有走被剖析的启动路径或 Hosting 遥测没到达采集器确认aspire run/aspire start启动了预期的 AppHost并在traces/profile.json中查找Aspire.Hosting.ProfilingscopeNo exported spans contained aspire.profiling.session_id剖析未启用或遥测未导出确认--capture-profile出现在--之前--之后的参数属于被包装命令并检查traces/profile.jsonNo profiling session contained correlated... spansCLI/Hosting/DCP span 未落入同一关联追踪检查traces/profile.json中缺失的 scope 或断裂的 parent/trace ID这套机制的完整技能说明见 startup-perf SKILL.md配合 Aspire.Cli/Profiling 目录下的四个源文件ProfileCaptureOptions、ProfileCaptureEnvironment、ProfileCaptureService、ProfileCaptureState可以完整复现从参数解析、环境变量注入、采集器生命周期到导出清理的全链路行为。【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspire创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表