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

.NET结合OpenTelemetry追踪Kafka链路预生产层级断裂问题

.NET中OpenTelemetry追踪Kafka消息链路跨服务关联失效问题

本地测试时,使用OpenTelemetry追踪Kafka消息全生命周期能在Jaeger UI中得到正确的追踪链路,但预生产环境中出现跨服务链路关联失效的问题:

  • 服务1的根Activity及其子节点显示正常
  • 服务2的根Activity及其子节点显示正常
  • 服务2的Activity无法关联到服务1的追踪树中,无法形成统一的层级结构

当前实现方案

  • 发送端:提取包含TraceId和SpanId的Activity.Id,存入消息头后发送消息
  • 接收端:消费消息后,通过ActivitySource创建新Activity,调用SetParentId传入00-traceid-spanid-flags格式的追踪字符串

已确认事项

  • 流程各环节均已创建ActivitySource并调用AddSource
  • 同一上下文内创建Activity时,未使用SetParentId,而是在父Activity未释放时创建新Activity
  • 使用最新版本的.NET、C#、OpenTelemetry及Confluent.Kafka

OpenTelemetry配置

services.AddOpenTelemetry().ConfigureResource(delegate (ResourceBuilder r)
{
    r.AddService(serviceName, environment, serviceVersion);
}).WithTracing(delegate (TracerProviderBuilder builder)
{
    builder
    .SetErrorStatusOnException()
    .AddAspNetCoreInstrumentation()
    .AddHttpClientInstrumentation()
    .AddAWSInstrumentation()
    .AddRedisInstrumentation()
    .AddSqlClientInstrumentation()
    .AddGrpcClientInstrumentation()
    .AddOtlpExporter()
    .AddSource("*")
    .SetSampler<AlwaysOnSampler>();
})
    .WithMetrics(delegate (MeterProviderBuilder builder)
    {
        //metrics
    });

相关伪代码示例

//Activity创建逻辑示例
internal class MyClass
{
    private readonly ActivitySource _activitySource = new(nameof(MyClass));

    internal Confluent.Kafka.Message<string,string> SaveTraceIntoMessage()
    {
        return new Message<string, string>()
        {
            Key = "message.Key",
            Value = JsonSerializer.Serialize(new
            {
                Headers = new []
                {
                    new string[] { "traceparent", Activity.Current.Id }
                }
            })
        };
    }

    //该方法实际属于另一个服务
    internal void ReceiveMessage()
    {
        var anotherActivitySource = new ActivitySource("Receiver");
        var activity = anotherActivitySource.CreateActivity("Receive",ActivityKind.Consumer);

        //模拟消费逻辑
        var consumeMessage = new Message<string, string>();
        var pretendIDeserializedTheValueofMessage = consumeMessage.Value;

        activity.SetParentId(pretendIDeserializedTheValueofMessage);
        activity.Start();

        //业务处理逻辑

        activity.Stop();
    }

    internal void ProduceMessage()
    {
        using var source = _activitySource.StartActivity("Produce");

        Confluent.Kafka.IProducer? producer = GetProducer();
        Confluent.Kafka.Message message = SaveTraceIntoMessage();

        producer!.Value.Produce(message);
    }

    private Confluent.Kafka.IProducer GetProducer()
    {
        //返回生产者实例
        return null;
    }
}

当前追踪链路效果

服务1与服务2的追踪链路各自独立展示,两个服务的根Activity及下属子节点均能正常显示,但无法建立跨服务的父子关联关系,无法形成统一的追踪层级树。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 18:42:45