恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
ASP.NET Core 实战:用 OTel Baggage 经 HttpClient 自动传递跨服务上下文
首页
资讯中心
/
ASP.NET Core 实战:用 OTel Baggage 经 HttpClient 自动传递跨服务上下文
ASP.NET Core 实战:用 OTel Baggage 经 HttpClient 自动传递跨服务上下文
发布时间:2026/10/15 2:20:06
示例工程【免费下载链接】practical-aspnetcorePractical samples of ASP.NET Core 11, 10, 9, 8.0, 7.0, 6.0, 5.0, 3.1, 2.2, and 2.1,projects you can use. Readme contains explanations on all projects.项目地址https://gitcode.com/gh_mirrors/pr/practical-aspnetcore点击查看免费下载本指南基于 practical-aspnetcore 仓库中的 open-telemetry-4 示例讲解如何在 ASP.NET Core 应用中记录 OpenTelemetryOTelBaggage并借助 HttpClient 探针自动以baggageHTTP 头把用户自定义属性传给下游 HTTP 请求。读完本文你将掌握Activity.AddBaggage的写入方式、Baggage 与 Span Attribute 的区别、baggage头的自动注入与手动注入两种路径以及如何在接收端读取并验证传递结果。一、什么是 OTel Baggage在 OpenTelemetry 中Baggage是随请求一起在服务之间传播的一组键值对key/value pairs由 W3CBaggage 规范定义。与 Trace 中的 Span 不同Span Attribute属性只属于当前 Span记录在当前服务的某个 trace 段上不会随请求传递给下游服务见仓库中的 open-telemetry-3 示例它演示了如何用SetTag记录project、location属性。Baggage绑定在请求上下文中可以跨越进程边界通过标准的baggageHTTP 请求头传递给下一个服务。典型使用场景包括把用户 ID、租户 ID、请求来源、A/B 实验分组等业务上下文从入口服务一路带到链路下游供各服务做路由、限流或观测过滤而无需在每个服务里重复解析业务参数。在 .NET 的System.Diagnostics.Activity模型中当前请求的上下文就是Activity.Current我们可以直接在它上面附加 Baggage。二、项目结构与依赖配置示例位于仓库 projects/open-telemetry/open-telemetry-4 目录只有三个文件open-telemetry-4/ ├── Program.cs # 全部逻辑 ├── Readme.md # 示例说明 └── open-telemetry-4.csproj # 项目文件open-telemetry-4.csproj 目标框架为net10.0仓库根目录的 global.json 将 SDK 锁定为 10.0.0 并允许rollForward: major引用的 OTel 相关包均为1.17.0Project SdkMicrosoft.NET.Sdk.Web PropertyGroup TargetFrameworknet10.0/TargetFramework ImplicitUsingstrue/ImplicitUsings /PropertyGroup ItemGroup PackageReference IncludeOpenTelemetry.Exporter.Console Version1.17.0 / PackageReference IncludeOpenTelemetry.Extensions.Hosting Version1.17.0 / PackageReference IncludeOpenTelemetry.Instrumentation.AspNetCore Version1.17.0 / PackageReference IncludeOpenTelemetry.Instrumentation.http Version1.17.0 / /ItemGroup /Project与仓库中前三个 OTel 示例open-telemetry-1、open-telemetry-2、open-telemetry-3相比本示例的关键差异是引入了OpenTelemetry.Instrumentation.HttpHTTP 客户端探针——正是它负责在出站请求上自动注入baggage头。注意 NuGet 包名大小写不敏感源码中写成的http与官方包名Http等价。三、核心实现拆解Program.cs 全部代码如下using System.Diagnostics; using OpenTelemetry.Trace; using OpenTelemetry.Resources; var builder WebApplication.CreateBuilder(); builder.Services.AddOpenTelemetry().WithTracing(b { b.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(builder.Environment.ApplicationName)) .AddHttpClientInstrumentation(); }); builder.Services.AddHttpClient(); builder.Logging.SetMinimumLevel(LogLevel.Information); WebApplication app builder.Build(); app.MapGet(/, async (HttpRequest request, IHttpClientFactory clientFactory) { Activity.Current?.AddBaggage (project, practical-aspnetcore); Activity.Current?.AddBaggage (location, Cairo); var baggage string.Join(,, Activity.Current.Baggage.ToDictionary(b b.Key, b b.Value).Select(x x.Key x.Value)); var client clientFactory.CreateClient(); //client.DefaultRequestHeaders.Add(baggage, baggage); var url request.Scheme :// request.Host /baggage; app.Logger.LogInformation(REQUEST URL url); var response await client.GetAsync(url); return Results.Text(Check the log, text/plain); }); app.MapGet(/baggage, (HttpRequest request) { var baggage request.Headers[baggage]; app.Logger.LogInformation($BAGGAGE VALUES {baggage}); return Results.Ok(); }); app.Run();3.1 启动阶段注册 OpenTelemetry 与 HTTP 客户端builder.Services.AddOpenTelemetry().WithTracing(b { b.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(builder.Environment.ApplicationName)) .AddHttpClientInstrumentation(); }); builder.Services.AddHttpClient();ResourceBuilder.CreateDefault().AddService(builder.Environment.ApplicationName)给 trace 资源打上service.name值为当前应用名与 open-telemetry-1 的用法一致。AddHttpClientInstrumentation()启用 HTTP 客户端探针监听出站请求并完成上下文含 Baggage注入。builder.Services.AddHttpClient()注册IHttpClientFactory后面通过工厂创建HttpClient。builder.Logging.SetMinimumLevel(LogLevel.Information)把日志级别调到 Information确保关键日志能在控制台看到本示例没有配置AddConsoleExporter因此观察点全部在应用日志上。3.2 写入 BaggageAddBaggage在根路由处理函数中通过两行代码把用户自定义属性写入当前 Activity 的 BaggageActivity.Current?.AddBaggage (project, practical-aspnetcore); Activity.Current?.AddBaggage (location, Cairo);这里Activity.Current是当前 HTTP 请求对应的 ActivityASP.NET Core 内建的Microsoft.AspNetCoreActivitySource 提供从 .NET 11 起该 Source 会原生填充 OTel 语义属性早期版本则依赖OpenTelemetry.Instrumentation.AspNetCore补充参见 net11/native-otel-tracing 说明。AddBaggage(key, value)以键值对形式把业务上下文挂到当前请求上下文上。紧随其后的这行代码展示了如何把 Baggage 序列化成标准的keyvalue列表var baggage string.Join(,, Activity.Current.Baggage.ToDictionary(b b.Key, b b.Value).Select(x x.Key x.Value));它先把Activity.Current.BaggageIEnumerableKeyValuePairstring, string转成字典再拼接为projectpractical-aspnetcore,locationCairo这样的 W3C Baggage 字符串——这正是手动注入方案下一节需要的头值。3.3 自动注入与手动注入两条路径示例中真正发起下游请求的代码是var client clientFactory.CreateClient(); //client.DefaultRequestHeaders.Add(baggage, baggage); var url request.Scheme :// request.Host /baggage; app.Logger.LogInformation(REQUEST URL url); var response await client.GetAsync(url);这里有两条传递路径值得重点区分自动路径示例实际采用AddHttpClientInstrumentation()启用后OpenTelemetry .NET SDK 会使用默认的传播器组合CompositeTextMapPropagator内含TraceContextPropagator与BaggagePropagator在出站请求上自动注入baggage头。因此上面被注释掉的手动加头代码不需要启用下游端点也能收到 Baggage。手动路径被注释的备选方案client.DefaultRequestHeaders.Add(baggage, baggage);直接复用上一节拼接好的 Baggage 字符串把baggage头手动写到HttpClient的默认请求头上。这一行注释在源码中Program.cs说明在开启 HTTP 客户端探针后自动注入已足够当你不想依赖探针、或需要精细控制头值时可取消注释并移除探针作为降级方案。3.4 接收端读取/baggage 端点app.MapGet(/baggage, (HttpRequest request) { var baggage request.Headers[baggage]; app.Logger.LogInformation($BAGGAGE VALUES {baggage}); return Results.Ok(); });下游端点直接从请求头request.Headers[baggage]取出 Baggage 值并写日志。整个示例形成一条完整回路GET /写入 Baggage → 借助 HttpClient 以baggage头发给GET /baggage→ 接收端读取头并输出BAGGAGE VALUES ...。四、运行与验证在仓库中进入示例目录并启动仓库根 global.json 指定 SDK 10.0.0dotnet run --project projects/open-telemetry/open-telemetry-4应用默认监听本地端口参考同仓库 open-telemetry-2 的运行输出地址为http://localhost:5000。随后访问入口端点curl http://localhost:5000/浏览器/curl 会得到Check the log文本真正的结果要看应用控制台日志。预期会依次出现两类日志推断自 Program.cs 的逻辑info: ... REQUEST URL http://localhost:5000/baggage info: ... BAGGAGE VALUES projectpractical-aspnetcore,locationCairoBAGGAGE VALUES一行即为验证结果GET /中通过AddBaggage写入的project与location两个键值已经以 W3Cbaggage头的形式传递到了/baggage端点并被成功解析。五、Baggage 与 Span Attribute 的取舍仓库中的 OTel 系列示例正好给出了同一组业务数据的两种记录方式open-telemetry-3用Activity.Current?.SetTag(project, practical-aspnetcore)写入Span Attribute控制台导出的 Span 中出现project、location标签但属性只留在本服务的当前 Span 内。open-telemetry-4本文用AddBaggage写入Baggage属性跟随baggage头跨服务传递。实际选型建议需要在本服务 trace 中检索/过滤、且不希望泄漏给下游 → 用 Span Attribute。需要随请求传给下游服务做决策或观测如租户隔离、灰度标记→ 用 Baggage。Baggage 会随每个出站请求传播应避免放入敏感信息如令牌、个人数据并注意控制键值数量与大小防止头膨胀影响链路性能。若想在 Baggage 之外同时让下游能按业务维度聚合 trace可结合 Attribute 一起记录二者并不互斥。六、小结通过本示例可以确认一条完整链路Activity.Current.AddBaggage写入业务上下文 →AddHttpClientInstrumentation按 W3C Baggage 规范自动注入baggage头 → 下游服务从请求头读取。这为 ASP.NET Core 分布式应用中用户属性 / 租户信息等轻量上下文跨服务透传提供了一个开箱即用的标准化方案也为后续把 Baggage 与 OTel 的 trace、metrics 打通留出了空间。赞分享示例工程【免费下载链接】practical-aspnetcorePractical samples of ASP.NET Core 11, 10, 9, 8.0, 7.0, 6.0, 5.0, 3.1, 2.2, and 2.1,projects you can use. Readme contains explanations on all projects.项目地址https://gitcode.com/gh_mirrors/pr/practical-aspnetcore点击查看免费下载相关推荐whichllm跨平台支持Windows、Linux与macOS硬件检测差异解析whichllm跨平台支持Windows、Linux与macOS硬件检测差异解析 whichllm是一款能够帮助用户找到在本地硬件上实际运行并表现最佳的LLM人工智能大模型本地部署CLImirrord 会话上下文如何穿越对象存储S3/GCS 签名上传链路的 baggage 传递实战mirrord 会话上下文如何穿越对象存储S3/GCS 签名上传链路的 baggage 传递实战 本文基于 mirrord Header Propagatio开发工具云原生CLIOpenCOOD中的压缩技术如何在有限带宽下实现高效协同感知OpenCOOD中的压缩技术如何在有限带宽下实现高效协同感知 OpenCOOD作为开源协同感知框架通过先进的压缩技术解决了车辆间通信的带宽瓶颈问题实现了在自动驾驶人工智能计算机视觉上一篇Micro框架GraphQL订阅重连机制客户端自动恢复连接下一篇Cream项目完全指南微软NAS与ViT技术大集合创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考