首页 > 解决方案 > Azure 应用服务从服务间请求中删除 Jaeger HTTP 标头

问题描述

我正在设置一个概念证明,其中包含两个都使用Jaeger检测的 ASP.NET Core 应用程序,以演示它如何通过网络在服务之间传播跟踪。这两个应用程序都被部署到 Azure App Services。

我正在使用OpenTracing Contrib包以 HTTP 标头的形式将 Jaeger 跟踪上下文自动注入到我的服务间流量中(该包被硬编码以使用这种传输形式)。但似乎这些标头在此过程中丢失了,因为接收应用程序无法恢复跟踪上下文。

在部署到 Azure 之前,我正在使用 Docker Compose 在本地测试应用程序,并且通过该设置,上下文传播工作正常。只有当应用程序在 Azure 中时,事情才会中断。

应用程序通过 HTTPS 进行通信,并且我已禁用 HSTS 和 HTTPS 重定向,以防可能导致 Azure 丢弃标头,基于上一个线程中的答案。

我还尝试在 Azure Container Instances 中运行这两个应用程序,这似乎是一个非首发 - 它没有修复上下文传播,并且似乎引入了更多关于跨度关系的错误。

这两个应用程序的设置几乎相同,只是它们服务的 API 端点不同。

我来自 program.cs 的 CreateWebHostBuild:

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .ConfigureServices(services =>
                {
                    // Registers and starts Jaeger (see Shared.JaegerServiceCollectionExtensions)
                    services.AddJaeger(CheckoutConfiguration.JaegerSettings.Host);

                    // Enables OpenTracing instrumentation for ASP.NET Core, CoreFx, EF Core
                    services.AddOpenTracing();
                });

AddJaeger 扩展方法的内容主要是从Contrib 示例中借用的

public static IServiceCollection AddJaeger(this IServiceCollection services, string jaegerHost = "localhost")
        {
            if (services == null)
                throw new ArgumentNullException(nameof(services));

            services.AddSingleton<ITracer>(serviceProvider =>
            {
                string serviceName = Assembly.GetEntryAssembly().GetName().Name;

                ILoggerFactory loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();

                ISampler sampler = new ConstSampler(sample: true);
                var reporter = new RemoteReporter.Builder()
                    .WithSender(new UdpSender(jaegerHost, 6831, 0))
                    .Build();

                ITracer tracer = new Tracer.Builder(serviceName)
                    .WithLoggerFactory(loggerFactory)
                    .WithReporter(reporter)
                    .WithSampler(sampler)
                    .Build();

                GlobalTracer.Register(tracer);

                return tracer;
            });

            var jaegerUri = new Uri($"http://{jaegerHost}:14268/api/traces");

            // Prevent endless loops when OpenTracing is tracking HTTP requests to Jaeger.
            services.Configure<HttpHandlerDiagnosticOptions>(options =>
            {
                options.IgnorePatterns.Add(request => jaegerUri.IsBaseOf(request.RequestUri));
                // We don't need to track Prometheus scraping requests
            });

            services.Configure<AspNetCoreDiagnosticOptions>(options => {
                // We don't need to trace Prometheus scraping requests
                options.Hosting.IgnorePatterns.Add(context => context.Request.Path.Equals("/metrics", StringComparison.OrdinalIgnoreCase));
            });

            return services;
        }

我的 startup.cs 配置方法表明我没有对标头做任何奇怪的事情(指标扩展适用于 prometheus-net)

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseHttpMetrics();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // Do release exception handling
            }

            app.UseMetricServer();

            app.UseMvc();
        }

我希望从一个应用程序到另一个应用程序的任何调用都会传播活动的 Jaeger 跟踪上下文。相反,这两个应用程序分别记录它们的跟踪,并且在 Jaeger UI 中无法辨别它们之间的链接。

这是一个应该跨越两个服务的跟踪的屏幕截图,但只显示了第一个服务的跨度:

断痕

标签: c#azureasp.net-coreazure-web-app-servicejaeger

解决方案


也许您应该检查一下您匆忙设置的应用程序服务是否都与运行 Jaeger 一体机实例的 VM 在同一个 azure 资源组中,否则第二个应用程序可能无法与 Jaeger 实例通信一点也不。


推荐阅读