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

.NET 8中跨边界启动/延续Activity的正确方式及Aspire追踪异常排查

问题

我运行着多个微服务处理大量工作负载,正尝试通过.NET Aspire追踪特定工作负载的流转路径,当前包含3个后台Worker项目与1个Web API项目。

第一个Worker在工作负载到达时启动Activity,完成后将其推入RabbitMQ队列,并将当前Activity的Id放入消息头;Worker 2处理后采用相同方式将消息推送给Worker 3,代码如下:

basicProperties.Headers = new Dictionary<String, Object>();

if (Activity.Current?.Id != null) 
{
    basicProperties.Headers.Add(DiagnosticsHandlerLoggingStrings.TraceParentHeaderName, Activity.Current?.Id);
}

Worker 2和3通过以下代码启动Activity:

if (basicProperties.Headers?.TryGetValue(DiagnosticsHandlerLoggingStrings.TraceParentHeaderName, out var parentActivityIdRaw) == true &&
    parentActivityIdRaw is Byte[] traceParentBytes) {
    parentActivityId = Encoding.UTF8.GetString(traceParentBytes);
}

return activitySource.StartActivity("Incoming message from queue", kind: ActivityKind.Consumer, parentId: parentActivityId);

最后Worker 3通过HttpClient调用Web API。但Aspire追踪页面仅显示Worker1、Worker3与Web API,未显示Worker2;且Worker3中自定义添加的事件未在详情页展示,仅显示HttpClient的事件。

我想了解跨边界延续Activity的正确方式,为何HttpClient能正常延续并上报事件,而自定义使用Activity.Current添加的事件无法在追踪详情中显示?


解决方案与说明

一、Worker2未出现在追踪中的原因及修复

  • Activity未绑定到当前上下文
    你当前代码仅启动了Activity但未将其设置为Activity.Current,导致Worker2的业务逻辑无法关联到该Activity。必须用using块自动管理Activity的上下文生命周期,确保整个处理流程都关联到这个Activity:

    using var activity = activitySource.StartActivity("Incoming message from queue", kind: ActivityKind.Consumer, parentId: parentActivityId);
    if (activity == null) return; // 追踪被禁用时StartActivity会返回null
    
    // 在这里执行Worker2的业务逻辑
    

    using块会自动将启动的Activity设为当前上下文,结束时恢复之前的状态,确保Aspire能采集到Worker2的追踪数据。

  • 缺少生产者Activity关联链路
    Worker2推送消息时,需要启动ActivityKind.Producer类型的子Activity,关联到当前的消费Activity,才能形成Worker2到Worker3的完整链路。你当前仅传递了父Activity ID,未创建生产者Activity,导致链路断裂:

    using var producerActivity = activitySource.StartActivity("Send message to queue", kind: ActivityKind.Producer);
    if (producerActivity != null)
    {
        basicProperties.Headers = new Dictionary<string, object>();
        basicProperties.Headers.Add(DiagnosticsHandlerLoggingStrings.TraceParentHeaderName, producerActivity.Id);
    }
    

    生产者Activity会自动关联到Worker2的消费Activity,形成父子关系,Aspire就能识别到Worker2的存在。

二、Worker3自定义事件未显示的原因及修复

  • 事件未关联到正确的Activity实例
    自定义事件必须调用当前Activity实例的AddEvent方法,而非仅依赖Activity.Current。正确做法是在启动Activity后直接操作该实例:

    using var activity = activitySource.StartActivity("Incoming message from queue", kind: ActivityKind.Consumer, parentId: parentActivityId);
    if (activity == null) return;
    
    // 添加自定义事件
    activity.AddEvent(new ActivityEvent("Custom Worker3 Event", DateTimeOffset.UtcNow));
    
    // 执行后续业务逻辑(包括HttpClient调用)
    

    HttpClient的Handler会自动获取Activity.Current并创建子Activity,所以能正常显示;如果自定义事件未绑定到当前Activity实例,Aspire无法采集到这些事件。

  • 确认ActivitySource被Aspire追踪
    检查Worker3的ActivitySource名称是否在Aspire的追踪配置中被包含,默认配置可能会排除部分来源。可在appsettings.json中明确配置:

    "Aspire": {
      "Telemetry": {
        "Tracing": {
          "IncludeActivitySources": [ "Your.Worker3.ActivitySource.Name" ]
        }
      }
    }
    

三、跨边界延续Activity的标准流程

  1. 生产者端

    • 启动ActivityKind.Producer类型的Activity,自动关联到当前上下文
    • 将该Activity的完整ID放入消息头(作为traceparent)
    • 用using块管理Activity生命周期,确保消息发送完成后正确结束
  2. 消费者端

    • 从消息头取出traceparent值
    • 启动ActivityKind.Consumer类型的Activity,指定parentId为取出的traceparent
    • 用using块绑定Activity到当前上下文,覆盖整个消费处理流程
    • 若需转发消息,重复生产者端的流程

内容的提问来源于stack exchange,提问作者Steen Tøttrup

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 14:22:17