Bagikan melalui


Pelacakan dan korelasi terdistribusi melalui olahpesan Bus Layanan

Salah satu masalah umum dalam pengembangan layanan mikro adalah kemampuan untuk melacak operasi dari klien melalui semua layanan yang terlibat dalam pemrosesan. Hal ini berguna untuk debugging, analisis kinerja, pengujian A / B, dan skenario diagnostik umum lainnya. Salah satu bagian dari masalah ini adalah melacak pekerjaan yang logis. Ini termasuk hasil pemrosesan pesan dan latensi dan panggilan dependensi eksternal. Bagian lain adalah korelasi kejadian diagnostik ini di luar batas proses.

Ketika produsen mengirim pesan melalui antrean, biasanya terjadi dalam lingkup beberapa operasi logis lainnya, yang diprakarsai oleh beberapa klien atau layanan lain. Operasi yang sama dilanjutkan oleh konsumen setelah menerima pesan. Baik produsen maupun konsumen (dan layanan lain yang memproses operasi), mungkin memancarkan peristiwa telemetri untuk melacak aliran dan hasil operasi. Untuk menghubungkan kejadian tersebut dan melacak operasi secara end-to-end, setiap layanan yang melaporkan telemetri harus memberi cap setiap kejadian dengan konteks jejak. Salah satu pustaka yang dapat membantu pengembang memiliki semua telemetri ini yang dipancarkan secara default adalah NServiceBus.

Perpesanan Microsoft Azure Service Bus telah menentukan properti muatan yang harus digunakan produsen dan konsumen untuk meneruskan konteks pelacakan tersebut. Protokol ini didasarkan pada W3C Trace-Context.

Nama Properti Deskripsi
Diagnostic-Id Pengidentifikasi unik panggilan eksternal dari produsen ke antrian. Lihat header traceparent W3C Trace-Context untuk formatnya

Pelacakan otomatis Service Bus .NET

Kelas ServiceBusProcessor klien Azure Messaging Service Bus untuk .NET menyediakan titik instrumentasi pelacakan yang dapat dihubungkan dengan sistem pelacakan, atau bagian dari kode klien. Instrumentasi memungkinkan pelacakan semua panggilan ke layanan perpesanan Service Bus dari sisi klien. Jika pemrosesan pesan dilakukan dengan menggunakan ProcessMessageAsync dari ServiceBusProcessor (pola penangan pesan), pemrosesan pesan juga diinstrumentasi.

Pelacakan dengan Azure Application Insights

Microsoft Application Insights menyediakan kemampuan pemantauan kinerja yang kaya termasuk permintaan otomagis dan pelacakan dependensi.

Bergantung pada jenis proyek Anda, instal Application Insights SDK:

Jika Anda menggunakan ProcessMessageAsync dari ServiceBusProcessor (pola message handler) untuk memproses pesan, pemrosesan pesan juga diinstrumentasi. Semua panggilan Bus Layanan yang dilakukan oleh layanan Anda secara otomatis dilacak dan dihubungkan dengan item telemetri lainnya. Jika tidak, lihat contoh berikut untuk pelacakan pemrosesan pesan manual.

Lacak pemrosesan pesan

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");
        }
    }
}

Dalam contoh ini, telemetri permintaan dilaporkan untuk setiap pesan yang diproses, memiliki tanda waktu, durasi, dan hasil (berhasil). Telemetri ini juga memiliki sekumpulan properti korelasi. Pelacakan dan pengecualian berlapis yang dilaporkan selama pemrosesan pesan juga dicap dengan properti korelasi yang mewakilinya sebagai 'anak' dari RequestTelemetry.

Jika Anda melakukan panggilan ke komponen eksternal yang didukung selama pemrosesan pesan, kompenen eksternal juga secara otomatis dilacak dan dikorelasikan. Lihat Melacak operasi kustom dengan Application Insights .NET SDK untuk pelacakan dan korelasi manual.

Jika Anda menjalankan kode eksternal selain Application Insights SDK, perkirakan untuk melihat durasi yang lebih lama saat melihat log Application Insights.

Durasi yang lebih lama di log Application Insights

Bukan berarti ada penundaan dalam menerima pesan tersebut. Dalam skenario ini, pesan telah diterima sejak pesan diteruskan sebagai parameter ke kode SDK. Dan, tag nama di log App Insights ()Proses) menunjukkan bahwa pesan tersebut sekarang sedang diproses oleh kode pemrosesan kejadian eksternal Anda. Masalah ini tidak terkait dengan Azure. Sebaliknya, metrik ini merujuk pada efisiensi kode eksternal Anda mengingat bahwa pesan tersebut telah diterima dari Bus Layanan.

Pelacakan dengan OpenTelemetry

Service Bus .NET Client library versi 7.5.0 dan yang lebih baru mendukung OpenTelemetry dalam mode eksperimental. Untuk informasi selengkapnya, lihat Pelacakan terdistribusi di .NET SDK.

Pelacakan tanpa sistem pelacakan

Jika sistem pelacakan Anda tidak mendukung pelacakan panggilan Bus Layanan otomatis, Anda mungkin ingin menambahkan dukungan tersebut ke dalam sistem pelacakan atau ke dalam aplikasi Anda. Bagian ini menjelaskan peristiwa diagnostik yang dikirim oleh Service Bus .NET client.

Service Bus .NET Client di instrumen menggunakan .NET tracing primitives System.Diagnostics.Activity and System.Diagnostics.DiagnosticSource.

Activity berfungsi sebagai konteks lacak, sedangkan DiagnosticSource adalah mekanisme pemberitahuan.

Jika tidak ada pendengar untuk kejadian DiagnosticSource, instrumentasi tidak aktif, sehingga tidak ada biaya instrumentasi. DiagnosticSource memberikan semua kontrol kepada pendengar:

  • pendengar mengontrol sumber dan kejadian mana yang akan didengarkan
  • pendengar mengontrol laju peristiwa dan pengambilan sampel
  • kejadian dikirim dengan payload yang memberikan konteks penuh sehingga Anda dapat mengakses dan memodifikasi objek Message selama kejadian tersebut

Pahami Panduan Pengguna DiagnosticSource sebelum melanjutkan penerapan.

Mari buat pendengar untuk kejadian Bus Layanan di aplikasi ASP.NET Core yang menulis log dengan Microsoft.Extenstion.Logger. Proses ini menggunakan pustaka System.Reactive.Core untuk berlangganan DiagnosticSource (juga mudah untuk berlangganan DiagnosticSource tanpa itu)

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();
    });
}

Dalam contoh ini, pendengar mencatat durasi, hasil, pengenal unik, dan waktu mulai untuk setiap operasi Bus Layanan.

Acara

Semua kejadian akan memiliki properti berikut yang sesuai dengan spesifikasi telemetri terbuka: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/api.md.

  • message_bus.destination – jalur antrean/topik/langganan
  • peer.address – namespace yang sepenuhnya memenuhi syarat
  • kind – baik produsen, konsumen, maupun klien. Produsen digunakan saat mengirim pesan, konsumen saat menerima, dan klien saat menyelesaikan.
  • componentservicebus

Semua peristiwa juga memiliki Entity properti dan Endpoint .

  • Entity - - Nama entitas (antrian, topik, dan sebagainya.)
  • Endpoint - URL titik akhir Bus Layanan

Operasi berinstrumen

Berikut daftar lengkap operasi berinstrumen:

Nama Operasi API yang Dilacak
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 Panggilan balik prosesor diatur pada ServiceBusProcessor. Properti ProcessMessageAsync
ServiceBusSessionProcessor.ProcessSessionMessage Panggilan balik prosesor diatur pada ServiceBusSessionProcessor. Properti ProcessMessageAsync

Pemfilteran dan pengambilan sampel

Dalam beberapa kasus, sebaiknya mencatat hanya sebagian peristiwa untuk mengurangi overhead kinerja atau konsumsi penyimpanan. Anda hanya dapat mencatat kejadian 'Stop' (seperti dalam contoh sebelumnya) atau sampel persentase kejadian. DiagnosticSource menyediakan cara untuk mencapainya dengan predikat IsEnabled. Untuk informasi selengkapnya, lihat Pemfilteran Berbasis Konteks di DiagnosticSource.

IsEnabled dapat dipanggil beberapa kali untuk satu operasi guna meminimalkan dampak kinerja.

IsEnabled dipanggil dalam urutan berikut:

  1. IsEnabled(<OperationName>, string entity, null) misalnya, IsEnabled("ServiceBusSender.Send", "MyQueue1"). Perhatikan bahwa tidak ada 'Start' atau 'Stop' di akhir. Gunakan ini untuk memfilter operasi atau antrean tertentu. Jika metode panggilan balik mengembalikan false, kejadian dari operasi tidak dikirim.

    • Untuk operasi 'Process' dan 'ProcessSession', Anda juga menerima panggilan balik IsEnabled(<OperationName>, string entity, Activity activity). Gunakan ini untuk memfilter kejadian berdasarkan activity.Id atau properti Tags.
  2. IsEnabled(<OperationName>.Start) misalnya, IsEnabled("ServiceBusSender.Send.Start"). Memeriksa apakah peristiwa 'Start' harus diaktifkan. Hasilnya hanya mempengaruhi kejadian 'Start', tetapi instrumentasi selanjutnya tidak bergantung padanya.

Tidak ada IsEnabled untuk kejadian 'Start'.

Jika beberapa hasil operasi merupakan pengecualian, IsEnabled("ServiceBusSender.Send.Exception") akan dipanggil. Anda hanya dapat berlangganan kejadian 'Exception' dan mencegah instrumentasi lainnya. Dalam hal ini, Anda masih harus menangani pengecualian tersebut. Karena instrumentasi lain dinonaktifkan, Anda harusnya tidak mengharapkan konteks pelacakan akan mengalir dengan pesan dari konsumen ke produsen.

Anda dapat menggunakan IsEnabled juga menerapkan strategi pengambilan sampel. Pengambilan sampel berdasarkan Activity.Id atau Activity.RootId memastikan pengambilan sampel yang konsisten di semua ban (selama disebarluaskan oleh sistem pelacakan atau dengan kode Anda sendiri).

Dengan adanya beberapa pendengar DiagnosticSource untuk sumber yang sama, cukup bagi satu pendengar saja untuk menerima kejadian, jadi tidak ada jaminan bahwa IsEnabled dipanggil.

Langkah berikutnya