You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET WebHost下OpenTelemetry跨服务父子Span关联异常排查

解决ASP.NET WebHost下OpenTelemetry跨服务Span父子关联问题

问题描述

基于ASP.NET搭建的微服务使用WebHost构建宿主,在Startup.cs配置OpenTelemetry链路追踪后,Jaeger可接收Span,但Telemetry服务调用Customer服务时,Customer的Span虽处于同一Trace中,却未作为Telemetry的子Span关联展示。同时Customer服务出现警告:

Open Telemetry spans are not properly gettings their parent's span ID. (invalid parent span IDs=; skipping clock skew adjustment)

已配置AddAspNetCoreInstrumentation和AddHttpClientInstrumentation,但跨服务Span传递未生效。

排查与修复步骤

1. 确保使用注入的HttpClient实例

Telemetry服务调用Customer服务时,必须使用依赖注入获取的HttpClient,而非手动new HttpClient()。手动创建的HttpClient不会被OpenTelemetry的AddHttpClientInstrumentation拦截,无法传递Trace上下文。

错误示例:

var client = new HttpClient();
await client.GetAsync("http://customer-service/api");

正确示例:

private readonly HttpClient _httpClient;

public TelemetryService(HttpClient httpClient)
{
    _httpClient = httpClient;
}

// 调用Customer服务
await _httpClient.GetAsync("http://customer-service/api");

2. 清理冗余的ResourceBuilder配置

配置中重复设置了ResourceBuilder,可能导致上下文传递异常,移除重复项:

修改Startup.cs中的OpenTelemetry配置:

public virtual IServiceProvider ConfigureServices(IServiceCollection services)
{
    // configure Open Telemetry
    services.AddOpenTelemetry()
        .ConfigureResource(resource => resource
            .AddService(
                serviceName: $"{Configuration["SubscriptionClientName"]} Service",
                serviceVersion: "1.0.0"))
        .WithTracing(builder => builder
            .SetSampler(new AlwaysOnSampler())
            .AddSource($"{Configuration["SubscriptionClientName"]} Service")
            // 移除重复的SetResourceBuilder调用
            .AddAspNetCoreInstrumentation()
            .AddHttpClientInstrumentation()
            .AddGrpcClientInstrumentation()
            .AddEntityFrameworkCoreInstrumentation()
            .AddOtlpExporter(options =>
            {
                options.Endpoint = new Uri("http://jaeger-allinone-collector.jaeger-observability.svc.cluster.local:4317");
                options.Protocol = OtlpExportProtocol.Grpc;
            }));
    ...
}

3. 验证AspNetCoreInstrumentation的头提取逻辑

Customer服务的AddAspNetCoreInstrumentation默认会提取W3C标准的traceparent头,若存在自定义中间件拦截请求头,需确保Trace相关头未被丢弃。可显式配置头提取规则(可选):

.AddAspNetCoreInstrumentation(options =>
{
    options.EnrichWithHttpRequest = (activity, request) =>
    {
        if (request.Headers.TryGetValue("traceparent", out var traceParent))
        {
            activity.SetTag("traceparent", traceParent.ToString());
        }
    };
})

4. 检查请求头传递情况

通过日志或抓包工具,确认Telemetry服务发送的请求中包含traceparent、tracestate等W3C Trace Context头,这些是父子Span关联的核心标识。

5. 统一OpenTelemetry包版本

所有微服务使用的OpenTelemetry相关NuGet包版本必须完全一致,版本不一致可能导致上下文序列化/反序列化异常。需统一的包包括:

  • OpenTelemetry
  • OpenTelemetry.Extensions.Hosting
  • OpenTelemetry.Instrumentation.AspNetCore
  • OpenTelemetry.Instrumentation.Http
  • OpenTelemetry.Exporter.OpenTelemetryProtocol

内容的提问来源于stack exchange,提问作者Metalzero2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:30:07