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

Application Insights端到端事务视图无法显示多个组件问题排查

问题分析与解决方案

你遇到的核心问题是分布式跟踪上下文未在Service Bus消息传递过程中完整传递:虽然所有日志和跟踪都带有正确的Operation Id(TraceId),但Application Insights的端到端事务时间线需要完整的调用链关联(包含Parent Id、TraceId的层级关系)才能展示多组件流程。仅靠相同的TraceId不足以构建可视化的时间线,必须确保消费端的遥测数据有正确的Parent Id指向发送端的原始请求。


1. 发送端:传递完整的分布式跟踪上下文

修改DemoModel的OnPost方法,不再只传递RootId,而是将当前Activity的完整跟踪上下文注入到Service Bus消息的自定义属性中:

public class DemoModel : PageModel
{
    private readonly ServiceBusSender _sender;

    public DemoModel(ServiceBusClient busClient)
    {
        _sender = busClient.CreateSender("actions");
    }

    public async Task OnPost()
    {
        var currentActivity = System.Diagnostics.Activity.Current;
        var message = new ServiceBusMessage($"Event: {currentActivity?.RootId}");
        
        // 注入完整的跟踪上下文到消息属性
        if (currentActivity != null)
        {
            message.ApplicationProperties["traceparent"] = currentActivity.Id;
            message.ApplicationProperties["tracestate"] = currentActivity.TraceStateString;
        }
        
        await _sender.SendMessageAsync(message);
    }
}

2. 消费端:恢复跟踪上下文并关联原始请求

在MessageHandler方法开头,从消息属性中提取跟踪上下文,创建关联的Activity,确保后续所有遥测数据都能关联到原始请求的调用链:

private async Task MessageHandler(ProcessMessageEventArgs arg)
{
    ServiceBusReceivedMessage message = arg.Message;
    _logger.LogInformation("Body:, {body}", message.Body.ToString());

    Activity? consumerActivity = null;
    // 从消息中提取跟踪上下文并启动关联的Activity
    if (message.ApplicationProperties.TryGetValue("traceparent", out var traceparentObj) 
        && traceparentObj is string traceparent)
    {
        consumerActivity = new Activity("ServiceBus.Consume")
            .SetParentId(traceparent);
        
        if (message.ApplicationProperties.TryGetValue("tracestate", out var tracestateObj) 
            && tracestateObj is string tracestate)
        {
            consumerActivity.TraceStateString = tracestate;
        }
        
        consumerActivity.Start();
    }

    try
    {
        using var scope = _serviceProvider.CreateScope();
        var client = scope.ServiceProvider.GetRequiredService<WeatherClient>();

        using (_telemetryClient.StartOperation<RequestTelemetry>("sub operation"))
        {
            var lisbon = client.GetWeatherAsync("lisbon");
            var london = client.GetWeatherAsync("london");
            await Task.WhenAll(lisbon, london);

            _logger.LogInformation("Weather, {body}", lisbon.Result?.Region);
            _logger.LogInformation("Weather, {body}", london.Result?.Region);
        }

        var paris = await client.GetWeatherAsync("paris");
        _logger.LogInformation("Weather, {body}", paris?.Region);

        await arg.CompleteMessageAsync(arg.Message);
    }
    finally
    {
        consumerActivity?.Stop();
    }
}

额外优化:使用SDK内置分布式跟踪

如果你使用的是Azure.Messaging.ServiceBus SDK(版本7.11.0及以上),可以直接启用内置的分布式跟踪,无需手动处理上下文传递:

在创建ServiceBusClient时配置启用跟踪:

var client = new ServiceBusClient(connectionString, new ServiceBusClientOptions
{
    EnableDistributedTracing = true
});

SDK会自动在发送消息时注入跟踪上下文,消费时自动恢复关联,简化代码逻辑。


验证要点

修改后检查Application Insights:

  • 消费端的sub operation请求遥测的ParentId应指向发送端POST请求的Id
  • 所有相关遥测(日志、请求、依赖项)的TraceId需与原始POST请求一致
  • 端到端事务时间线会自动展示MVC请求、Service Bus消息传递、消费端处理的完整流程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:55:30