Distribuované trasování a korelace prostřednictvím zasílání zpráv služby Service Bus

Jedním z běžných problémů při vývoji mikroslužeb je schopnost trasovat operace z klienta prostřednictvím všech služeb, které jsou součástí zpracování. Je užitečné pro ladění, analýzu výkonu, testování A/B a další typické diagnostické scénáře. Jednou z částí tohoto problému je sledování logických částí práce. Zahrnuje výsledky zpracování zpráv a latenci a volání externích závislostí. Další částí je korelace těchto diagnostických událostí za hranicemi procesu.

Když producent odešle zprávu prostřednictvím fronty, obvykle k ní dochází v oboru jiné logické operace iniciované jiným klientem nebo službou. Stejná operace pokračuje příjemcem, jakmile obdrží zprávu. Producent i příjemce (a další služby, které operaci zpracovávají), pravděpodobně generují telemetrické události, aby se trasování toku operace a výsledku. Aby bylo možné tyto události korelovat a provádět kompletní operace trasování, každá služba, která hlásí telemetrii, musí každou událost kolovat s kontextem trasování. Jedna knihovna, která vývojářům může pomoct, aby tato telemetrie ve výchozím nastavení vygenerovala, je NServiceBus.

Zasílání zpráv služby Microsoft Azure Service Bus definovalo vlastnosti datové části, které by producenti a příjemci měli použít k předání takového kontextu trasování. Protokol je založený na kontextu trasování W3C.

Název vlastnosti Popis
ID diagnostiky Jedinečný identifikátor externího volání od producenta do fronty. Informace o formátu najdete v hlavičce trasování a kontextu trasování W3C.

Automatické odčítání klienta služby Service Bus .NET

Třída ServiceBusProcessor klienta služby Azure Messaging Service Bus pro .NET poskytuje body instrumentace trasování, které je možné připojit pomocí trasovacích systémů nebo kus kódu klienta. Instrumentace umožňuje sledovat všechna volání do služby zasílání zpráv service Bus ze strany klienta. Pokud je zpracování zpráv provedeno pomocí ProcessMessageAsync ServiceBusProcessor (vzor obslužné rutiny zprávy), zpracování zpráv je také instrumentováno.

Sledování pomocí Aplikace Azure lication Insights

Microsoft Application Insights poskytuje bohaté možnosti monitorování výkonu, včetně automatického požadavku a sledování závislostí.

V závislosti na typu projektu nainstalujte sadu Application Insights SDK:

Pokud ke zpracování zpráv používáte ProcessMessageAsync ServiceBusProcessor (vzor obslužné rutiny zpráv), je také instrumentováno zpracování zpráv. Všechna volání služby Service Bus provedená vaší službou se automaticky sledují a korelují s ostatními položkami telemetrie. V opačném případě se podívejte na následující příklad pro sledování ručního zpracování zpráv.

Trasování zpracování zpráv

async Task ProcessAsync(ProcessMessageEventArgs args)
{
    ServiceBusReceivedMessage message = args.Message;
    if (message.ApplicationProperties.TryGetValue("Diagnostic-Id", out var objectId) && objectId is string diagnosticId)
    {
        var activity = new Activity("ServiceBusProcessor.ProcessMessage");
        activity.SetParentId(diagnosticId);
        // If you're using Microsoft.ApplicationInsights package version 2.6-beta or higher, you should call StartOperation<RequestTelemetry>(activity) instead
        using (var operation = telemetryClient.StartOperation<RequestTelemetry>("Process", activity.RootId, activity.ParentId))
        {
            telemetryClient.TrackTrace("Received message");
            try 
            {
            // process message
            }
            catch (Exception ex)
            {
                telemetryClient.TrackException(ex);
                operation.Telemetry.Success = false;
                throw;
            }

            telemetryClient.TrackTrace("Done");
        }
    }
}

V tomto příkladu se hlásí telemetrie požadavků pro každou zpracovanou zprávu, časové razítko, dobu trvání a výsledek (úspěch). Telemetrie má také sadu vlastností korelace. Vnořené trasování a výjimky hlášené během zpracování zpráv jsou také označeny vlastnostmi korelace představujícími je jako "podřízené" objektu RequestTelemetry.

V případě, že během zpracování zpráv voláte podporované externí komponenty, budou se také automaticky sledovat a korelovat. Informace o ručním sledování a korelaci najdete v tématu Sledování vlastních operací pomocí sady Application Insights .NET SDK .

Pokud kromě sady Application Insights SDK spouštíte jakýkoli externí kód, při prohlížení protokolů Application Insights se očekává delší doba trvání .

Delší doba trvání v protokolu Application Insights

Neznamená to, že při přijetí zprávy došlo ke zpoždění. V tomto scénáři již byla zpráva přijata, protože zpráva je předána jako parametr kódu sady SDK. A značka názvu v protokolech App Insights (Proces) označuje, že zpráva se teď zpracovává kódem pro zpracování externích událostí. Tento problém nesouvisí s Azure. Místo toho tyto metriky odkazují na efektivitu vašeho externího kódu vzhledem k tomu, že zpráva už byla přijata ze služby Service Bus.

Sledování pomocí OpenTelemetry

Klientská knihovna service Bus .NET verze 7.5.0 a novější podporuje OpenTelemetry v experimentálním režimu. Další informace naleznete v tématu Distribuované trasování v sadě .NET SDK.

Sledování bez trasování systému

V případě, že systém trasování nepodporuje automatické sledování volání služby Service Bus, můžete se podívat na přidání takové podpory do systému trasování nebo do vaší aplikace. Tato část popisuje diagnostické události odeslané klientem .NET služby Service Bus.

Klient .NET service Bus je instrumentovaný pomocí trasování .NET primitives System.Diagnostics.Activity a System.Diagnostics.DiagnosticSource.

Activity slouží jako kontext trasování v době, kdy DiagnosticSource se jedná o mechanismus oznámení.

Pokud pro události DiagnosticSource není žádný naslouchací proces, instrumentace je vypnutá, čímž se zachovají nulové náklady na instrumentaci. DiagnosticSource poskytuje všem ovládacím prvkům naslouchacímu procesu:

  • Naslouchací proces řídí, které zdroje a události se mají naslouchat
  • Naslouchací proces řídí rychlost událostí a vzorkování.
  • události se odesílají s datovou částí, která poskytuje úplný kontext, abyste během události mohli přistupovat k objektu zprávy a upravovat je.

Než budete pokračovat v implementaci, seznamte se s uživatelskou příručkou DiagnosticSource.

Pojďme vytvořit naslouchací proces pro události služby Service Bus v aplikaci ASP.NET Core, která zapisuje protokoly pomocí microsoft.Extension.Loggeru. Používá knihovnu System.Reactive.Core k přihlášení k odběru DiagnosticSource (bez ní se také dá snadno přihlásit k odběru DiagnosticSource).

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory factory, IApplicationLifetime applicationLifetime)
{
    // configuration...

    var serviceBusLogger = factory.CreateLogger("Azure.Messaging.ServiceBus");

    IDisposable innerSubscription = null;
    IDisposable outerSubscription = DiagnosticListener.AllListeners.Subscribe(delegate (DiagnosticListener listener)
    {
        // subscribe to the Service Bus DiagnosticSource
        if (listener.Name == "Azure.Messaging.ServiceBus")
        {
            // receive event from Service Bus DiagnosticSource
            innerSubscription = listener.Subscribe(delegate (KeyValuePair<string, object> evnt)
            {
                // Log operation details once it's done
                if (evnt.Key.EndsWith("Stop"))
                {
                    Activity currentActivity = Activity.Current;
                    serviceBusLogger.LogInformation($"Operation {currentActivity.OperationName} is finished, Duration={currentActivity.Duration}, Id={currentActivity.Id}, StartTime={currentActivity.StartTimeUtc}");
                }
            });
        }
    });

    applicationLifetime.ApplicationStopping.Register(() =>
    {
        outerSubscription?.Dispose();
        innerSubscription?.Dispose();
    });
}

V tomto příkladu naslouchací proces zaznamená dobu trvání, výsledek, jedinečný identifikátor a čas spuštění pro každou operaci Service Bus.

Události

Všechny události budou mít následující vlastnosti, které odpovídají specifikaci otevřené telemetrie: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/api.md.

  • message_bus.destination – fronta, téma/ cesta předplatného
  • peer.address – plně kvalifikovaný obor názvů
  • kind – buď producent, spotřebitel, nebo klient. Producent se používá při odesílání zpráv, příjemce při příjmu a klient při usídlení.
  • componentservicebus

Všechny události mají Entity také vlastnosti a Endpoint vlastnosti.

  • Entity – – Název entity (fronta, téma atd.)
  • Endpoint – Adresa URL koncového bodu služby Service Bus

Instrumentované operace

Tady je úplný seznam instrumentovaných operací:

Název operace Sledované rozhraní API
ServiceBusSender.Send ServiceBusSender.SendMessageAsync
ServiceBusSender.SendMessagesAsync
ServiceBusSender.Schedule ServiceBusSender.ScheduleMessageAsync
ServiceBusSender.ScheduleMessagesAsync
ServiceBusSender.Cancel ServiceBusSender.CancelScheduledMessageAsync
ServiceBusSender.CancelScheduledMessagesAsync
ServiceBusReceiver.Receive ServiceBusReceiver.ReceiveMessageAsync
ServiceBusReceiver.ReceiveMessagesAsync
ServiceBusReceiver.ReceiveDeferred ServiceBusReceiver.ReceiveDeferredMessagesAsync
ServiceBusReceiver.Peek ServiceBusReceiver.PeekMessageAsync
ServiceBusReceiver.PeekMessagesAsync
ServiceBusReceiver.Abandon ServiceBusReceiver.AbandonMessagesAsync
ServiceBusReceiver.Complete ServiceBusReceiver.CompleteMessagesAsync
ServiceBusReceiver.DeadLetter ServiceBusReceiver.DeadLetterMessagesAsync
ServiceBusReceiver.Defer ServiceBusReceiver.DeferMessagesAsync
ServiceBusReceiver.RenewMessageLock ServiceBusReceiver.RenewMessageLockAsync
ServiceBusSessionReceiver.RenewSessionLock ServiceBusSessionReceiver.RenewSessionLockAsync
ServiceBusSessionReceiver.GetSessionState ServiceBusSessionReceiver.GetSessionStateAsync
ServiceBusSessionReceiver.SetSessionState ServiceBusSessionReceiver.SetSessionStateAsync
ServiceBusProcessor.ProcessMessage Zpětné volání procesoru nastavené na ServiceBusProcessor. ProcessMessageAsync – vlastnost
ServiceBusSessionProcessor.ProcessSessionMessage Zpětné volání procesoru nastavené na ServiceBusSessionProcessor. ProcessMessageAsync – vlastnost

Filtrování a vzorkování

V některýchpřípadechch Můžete protokolovat pouze události Stop (jako v předchozím příkladu) nebo ukázkové procento událostí. DiagnosticSource poskytnout způsob, jak toho dosáhnout s predikátem IsEnabled . Další informace naleznete v tématu Kontextové filtrování v DiagnosticSource.

IsEnabled může být volána vícekrát pro jednu operaci, aby se minimalizoval dopad na výkon.

IsEnabled je volána v následující sekvenci:

  1. IsEnabled(<OperationName>, string entity, null) například IsEnabled("ServiceBusSender.Send", "MyQueue1"). Všimněte si, že na konci není žádná možnost Start ani Stop. Slouží k filtrování konkrétních operací nebo front. Pokud metoda zpětného volání vrátí false, události operace se neodesílají.

    • U operací Process a ProcessSession také obdržíte IsEnabled(<OperationName>, string entity, Activity activity) zpětná volání. Slouží k filtrování událostí na activity.Id základě vlastností značky.
  2. IsEnabled(<OperationName>.Start) například IsEnabled("ServiceBusSender.Send.Start"). Zkontroluje, jestli se má aktivovat událost Start. Výsledek ovlivňuje pouze událost Start, ale další instrumentace na ní nezávisí.

IsEnabled Není k dispozici žádná událost Stop.

Pokud je výsledkem operace výjimka, IsEnabled("ServiceBusSender.Send.Exception") je volána. Můžete se přihlásit pouze k odběru událostí výjimky a zabránit zbytku instrumentace. V takovém případě stále musíte tyto výjimky zpracovat. Vzhledem k tomu, že jiná instrumentace je zakázaná, neměli byste očekávat, že kontext trasování bude proudit se zprávami od příjemce k producentovi.

Můžete také použít IsEnabled implementaci strategií vzorkování. Vzorkování na základě nebo Activity.RootId zajištění konzistentního Activity.Id vzorkování napříč všemi pneumatikami (pokud se šíří systémem trasování nebo vlastním kódem).

V přítomnosti více DiagnosticSource naslouchacích procesů pro stejný zdroj stačí, aby událost přijali jenom jeden naslouchací proces, takže neexistuje žádná záruka, která IsEnabled se volá.

Další kroky