Azure App Service从服务间请求中删除Jaeger HTTP标头

时间:2019-08-08 20:05:33

标签: c# azure asp.net-core azure-web-sites jaeger

我正在建立一个概念证明,其中包含两个都装有Jaeger的ASP.NET Core应用程序,以演示它如何在线路之间传播跟踪。这两个应用程序都将部署到Azure App Services。

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

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

应用程序通过HTTPS进行通信,并且根据this previous thread中的答案,我已经禁用了HSTS和HTTPS重定向,以防可能导致Azure删除标头。

我也尝试过在Azure容器实例中运行这两个应用程序,但这似乎不是一个开始-它不能解决上下文传播问题,并且似乎会在跨度关系方面引入更多错误。

这两个应用程序的设置几乎完全相同,只是它们所服务的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();
                });

主要从the Contrib sample借用的AddJaeger扩展方法的内容:

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中无法识别它们之间的链接。

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

Broken trace

1 个答案:

答案 0 :(得分:0)

也许您应该检查一下急于设置的应用程序服务是否与运行Jaeger多合一实例的VM都在同一个Azure资源组中,否则第二个应用程序可能无法与之通信就是Jaeger实例。