تتبع الموزعة والارتباط من خلال المراسلة Service Bus
واحدة من المشاكل الشائعة في تطوير الخدمات الصغيرة هي القدرة على تتبع العملية من العميل من خلال جميع الخدمات المشاركة في المعالجة. من المفيد تصحيح الأخطاء وتحليل الأداء واختبار A/B وسيناريوهات التشخيص النموذجية الأخرى. أحد أجزاء هذه المشكلة هو تتبع قطعة منطقية من العمل. وهذا يتضمن نتيجة معالجة الرسائل وزمن الانتقال واستدعاءات التبعية الخارجية. جزء آخر هو ارتباط هذه الأحداث التشخيصية بما يتجاوز حدود العملية.
عندما يرسل منتج رسالة عبر قائمة انتظار، يحدث ذلك عادة في نطاق بعض العمليات المنطقية الأخرى، التي بدأها عميل أو خدمة أخرى. يتم مواصلة نفس العملية من قبل المستهلك بمجرد أن يتلقى رسالة. ومن المفترض أن يقوم كل من المنتج والمستهلك (والخدمات الأخرى التي تعالج العملية) ببعث أحداث telemetry لتتبع تدفق العملية ونتيجتها. من أجل ربط مثل هذه الأحداث وتتبع العملية الشاملة، كل خدمة تقرر أنه يجب علي telemetry أن توفر خوادم مخصصة القياس لكل حدث مع سياق التتبع.
وقد حددت رسائل Microsoft Azure Service Bus خصائص البيانات الأساسية التي ينبغي أن يستخدمها المنتجون والمستهلكون لتمرير سياق التتبع. يعتمد البروتوكول على W3C Trace-Context.
اسم الخاصية | الوصف |
---|---|
معرف التشخيص | المعرف الفريد للاستدعاءات الخارجية من المنتج إلى قائمة الانتظار. ارجع إلى عنوان التتبع W3C Trace-Context للحصول على التنسيق |
تعقب عميل Service Bus .NET
ServiceBusProcessor
توفر فئة عميل Azure Messaging Service Bus لـ .NET نقاط أدوات التتبع التي يمكن ربطها بواسطة أنظمة التتبع أو قطعة من التعليمات البرمجية للعميل. يسمح الجهاز بتتبع كافة الاستدعاءات إلى خدمة المراسلة Service Bus من جانب العميل. إذا تمت معالجة الرسائل باستخدام ProcessMessageAsync
من ServiceBusProcessor
(نمط معالج الرسالة) ، يتم أيضًا وضع علامة علي معالجة الرسالة.
التعقب باستخدام Azure Application Insights
يوفر Microsoft Application Insights قدرات مراقبة الأداء الغنية بما في ذلك طلب تلقائي وتعقب التبعية.
اعتمادًا على نوع المشروع، «install» عدة تطوير برامج Application Insights:
- ASP.NET -- «install» الإصدار 2.5 - beta2 أو أعلى
- ASP.NET -- «install» الإصدار 2.2.0 - beta2 أو أعلى توفر هذه الارتباطات تفاصيل تتعلق بتثبيت SDK وإنشاء الموارد وتكوين SDK (إذا لزم الأمر). بالنسبة للتطبيقات غير التابعة لـ ASP.NET، راجع Azure Application Insights للحصول على مقالة Console Applications
إذا استخدمتProcessMessageAsync
منServiceBusProcessor
(نمط معالج الرسالة) لمعالجة الرسائل، يتم أيضًا وضع علامة على معالجة الرسالة. يتم تعقب جميع استدعاءات Service Bus التي تم إجراؤها بواسطة الخدمة تلقائيًّا وترتبط بعناصر telemetry الأخرى. وإلا بالإشارة إلى المثال التالي لتعقب معالجة الرسائل اليدوية.
تعقب معالجة الرسائل
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");
}
}
}
في هذا المثال، يتم الإبلاغ عن telemetry لكل رسالة تمت معالجتها، ذات طابع زمني ومدة ونتيجة (نجاح). يحتوي telemetry أيضًا على مجموعة من خصائص الارتباط. يتم أيضًا ختم عمليات التتبع والاستثناءات المتداخلة التي تم الإبلاغ عنها أثناء معالجة الرسالة بخصائص الارتباط التي تمثلها كـ "توابع" لـRequestTelemetry
في حالة قيامك باستدعاءاتك إلى المكونات الخارجية المعتمدة أثناء معالجة الرسائل، يتم تعقبها وربطها تلقائيًّا. الرجوع إلى تعقب العمليات المخصصة مع عدة تطوير برامج Application Insights .NET للتعقب اليدوي والارتباط.
إذا كنت تقوم بتشغيل أية تعليمات برمجية خارجية بالإضافة إلى عدة تطوير برامج التطبيق Application Insights SDK، تتوقع مدة أطول عند عرض سجلات Application Insights.
هذا لا يعني أنه إذا كان هناك تأخير في تلقي الرسالة. في هذا السيناريو، تم استلام الرسالة بالفعل منذ تمرير الرسالة كمعلمة إلى التعليمة البرمجية SDK وعلامة الاسم في سجلات App Insights(العملية)يشير إلى أن الرسالة الآن يتم معالجتها بواسطة رمز معالجة الأحداث الخارجية. هذه المشكلة غير متعلقة بـ Azure. بدلًا من ذلك، تشير هذه المقاييس إلى كفاءة التعليمات البرمجية الخارجية الخاصة بك نظرًا لأن الرسالة قد تم استلامها بالفعل من Service Bus.
التتبع باستخدام OpenTelemetry
يدعم الإصدار 7.5.0 من مكتبة عميل .NET لناقل الخدمة والإصدارات الأحدث OpenTelemetry في الوضع التجريبي. لمزيد من المعلومات، راجع التتبع الموزع في .NET SDK.
التتبع بدون تتبع النظام
في حالة عدم دعم نظام التتبع الخاص بك لتتبع استدعاءات Service Bus التلقائية، قد تبحث عن إضافة هذا الدعم إلى نظام تتبع أو إلى التطبيق الخاص بك. يصف هذا المقطع أحداث التشخيص المرسلة بواسطة عميل Service Bus .NET
يضع عميل Service Bus .NET علامة باستخدام أساسيات تتبع .NET وهيSystem.Diagnostics.Activity و System.Diagnostics.DiagnosticSource.
Activity
يعمل كسياق تتبع بينما DiagnosticSource
هو آلية إعلام.
إذا لم يكن هناك وحدة استماع لأحداث DiagnosticSource ، فإن الأجهزة مطفأة، مع الاحتفاظ بتكاليف الأجهزة صفر. يوفر DiagnosticSource عنصر تحكم إلى وحدة الاستماع:
- يتحكم المستمع في المصادر والأحداث التي يجب الاستماع إليها
- تقوم عناصر بالتحكم في معدل الحدث وأخذ العينات
- يتم إرسال الأحداث بالبيانات الأساسية التي توفر السياق الكامل بحيث يمكنك الوصول إلى كائن الرسالة وتعديلها أثناء الحدث
تعرف على دليل مستخدم DiagnosticSource قبل المتابعة في التنفيذ.
فلنعمل على إنشاء وحدة الاستماع لأحداث Service Bus في تطبيقات ASP.NET التي تكتب السجلات باستخدام Microsoft.Extension.Logger. ويستخدم مكتبة System.Reactive.Core للاشتراك في DiagnosticSource (كما أنه من السهل أيضًا الاشتراك في 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();
});
}
في هذا المثال، مدة تسجيلات وحدة الاستماع والنتيجة والمعرف الفريد ووقت بدء كل عملية Service Bus.
الأحداث
سيكون لكافة الأحداث الخصائص التالية التي تتوافق مع مواصفات بيانات تتبع الاستخدام المفتوحة: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/api.md .
message_bus.destination
- مسار قائمة الانتظار/ الموضوع/ الاشتراكpeer.address
- مساحة اسم مؤهلة بالكاملkind
- إما منتج أو عميل أو مستهلك يُستخدم المنتج عند إرسال الرسائل، والمستهلك عند الاستلام والعميل عند التسوية.component
–servicebus
تحتوي جميع الأحداث أيضا على Entity
خصائص و Endpoint
.
Entity
- - اسم الكيان (قائمة الانتظار والموضوع وما إلى ذلك.)Endpoint
- «URL» نقطة نهاية Service Bus
العمليات التي تم وضع علامة عليها
فيما يلي القائمة الكاملة للعمليات التي تم وضع علامات عليها:
اسم العملية | 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 | Processor callback set on ServiceBusProcessor. خاصية ProcessMessageAsync |
ServiceBusSessionProcessor.ProcessSessionMessage | تعيين استدعاء المعالج في ServiceBusSessionProcessor. خاصية ProcessMessageAsync |
التصفية وأخذ عينات
في بعض الحالات، من المستحسن تسجيل جزء فقط من الأحداث لتقليل حمل الأداء أو استهلاك التخزين. يمكنك تسجيل أحداث 'Stop' فقط (كما في المثال السابق) أو عينة من الأحداث.
DiagnosticSource
توفير طريقة لتحقيق ذلك مع IsEnabled
المسند. لمزيد من المعلومات، راجع التصفية المستندة إلى السياق في DiagnosticSource.
IsEnabled
قد يتم الاستدعاء عدة مرات لعملية واحدة لتقليل تأثير الأداء.
يتم استدعاء IsEnabled
في التسلسل التالي:
IsEnabled(<OperationName>, string entity, null)
على سبيل المثال،IsEnabled("ServiceBusSender.Send", "MyQueue1")
. لاحظ أنه لا يوجد 'Start' أو 'Stop' في النهاية. استخدامه لتصفية عمليات معينة أو قوائم الانتظار. إذا كان أسلوب رد الاتصال بإرجاعfalse
، لا يتم إرسال الأحداث للعملية.- بالنسبة لعمليات 'Process' و'ProcessSession' ، تتلقى أيضًا
IsEnabled(<OperationName>, string entity, Activity activity)
رد الاتصال. استخدامه لتصفية الأحداث استنادًا إلىactivity.Id
أو خصائص العلامات.
- بالنسبة لعمليات 'Process' و'ProcessSession' ، تتلقى أيضًا
IsEnabled(<OperationName>.Start)
على سبيل المثال،IsEnabled("ServiceBusSender.Send.Start")
. التحقق مما إذا كان يجب تشغيل حدث "Start". تؤثر النتيجة فقط على حدث "Start"، ولكن لا تعتمد عليه أجهزة أخرى.
لا يوجد IsEnabled
لحدث "Stop".
إذا كانت بعض نتائج العملية استثناء، يتم استدعاءIsEnabled("ServiceBusSender.Send.Exception")
. يمكنك الاشتراك فقط في أحداث "Exception" ومنع بقية الأجهزة. في هذه الحالة، لا يزال يتعين عليك التعامل مع مثل هذه الاستثناءات. حيث إن الأجهزة الأخرى معطلة، فلا يجب أن تتوقع تدفق سياق التتبع مع الرسائل من المستهلك إلى المنتج.
يمكنك أيضًا استخدام IsEnabled
وتنفيذ إستراتيجيات أخذ العينات. أخذ العينات على أساس Activity.Id
أو يضمن أخذ عينات Activity.RootId
متسقة عبر جميع الإطارات (طالما أنها تنتشر عن طريق نظام التتبع أو من قبل التعليمات البرمجية الخاصة بك).
في وجود DiagnosticSource
وحدات استماع متعددة لنفس المصدر، يكفي لوحدة استماع واحدة قبول الحدث، لذلك ليس هناك ضمان يسمىIsEnabled
.
الخطوات التالية
- ارتباط Application Insights
- مراقبة تبعيات Application Insights لمعرفة ما إذا كان REST أو SQL أو الموارد الخارجية الأخرى تؤدي إلى إبطائك.
- تعقب العمليات المخصصة باستخدام Application Insights .NET SDK