البدء بـ Reliable Services

يحتوي تطبيق Azure Service Fabric على خدمة واحدة أو أكثر لتشغيل التعليمة البرمجية الخاصة بك. يوضح لك هذا الدليل كيفية إنشاء تطبيقات Service Fabric بنوعيها ذات حالة وعديم الحالة باستخدام Reliable Services.

تحقق من هذه الصفحة للحصول على فيديو تدريبي يوضح لك أيضًا كيفية إنشاء خدمة Reliable ذات حالة.

المفاهيم الأساسية

للبدء في استخدام Reliable Services، فقط تحتاج لمعرفة بعض المفاهيم الأساسية:

  • نوع الخدمة: هذا خاص بتنفيذ الخدمة الخاصة بك. يتم تعريف الخدمة من خلال الفئة التي تكتبها والتي تتجاوز StatelessService وأي رمز أو تبعيات أخرى مستخدمة فيها مع اسم ورقم الإصدار.
  • مثيل الخدمة المسماة: لتشغيل الخدمة، تقوم بإنشاء مثيلات مسماة من نوع الخدمة الخاصة بك بنفس طريقة إنشاء مثيلات كائن من نوع فئة. يحتوي مثيل الخدمة على اسم في شكل عنوان URI باستخدام "النسيج:/" مخطط، مثل "النسيج: / MyApp / MyService".
  • مضيف الخدمة: تحتاج مثيلات الخدمة المسماة التي تنشئها إلى التشغيل داخل عملية مضيف. مضيف الخدمة هو مجرد عملية يمكن فيها تشغيل مثيلات خدمتك.
  • تسجيل الخدمة: التسجيل يجمع كل شئ معا. يجب تسجيل نوع الخدمة مع وقت تشغيل Service Fabric في مضيف خدمة للسماح لـ Service Fabric بإنشاء مثيلات منه للتشغيل.

إنشاء خدمة بدون حالة

الخدمة بدون حالة هي أحد أنواع الخدمات التي تُعد حاليا السائدة في التطبيقات السحابية. تعتبر بدون حالة لأن الخدمة نفسها لا تحتوي على بيانات تحتاج إلى تخزينها بشكل موثوق أو إتاحتها على نطاق واسع. وفي حالة إيقاف تشغيل مثيل خدمة بدون حالة، فإن كل حالتها الداخلية يتم فقدانها. في هذا النوع من الخدمات، يجب أن تستمر الحالة في مخزن خارجي، مثل Azure Tables أو قاعدة بيانات SQL، حتى تكون متاحة وموثوقة للغاية.

قم بتشغيل Visual Studio 2017 أو Visual Studio 2019 بصلاحيات مسؤول، وقم بإنشاء مشروع تطبيق Service Fabric جديد باسم HelloWorld:

استخدام مربع الحوار مشروع جديد لإنشاء تطبيق Service Fabric جديد

ثم قم بإنشاء مشروع خدمة بدون حالة باستخدام NET Core 2.0 المسمى HelloWorldStateless:

في مربع الحوار الثاني، أنشئ مشروع خدمة عديمة الحالة

يحتوي الحل الخاص بك الآن على مشروعين:

  • HelloWorld. هذا هو مشروع التطبيق الذي يحتوي على خدماتك. ويحتوي كذلك على بيان التطبيق الذي يصف التطبيق وعدد برامج PowerShell النصية التي تساعدك على توزيع التطبيق الخاص بك.
  • HelloWorldStateless. هذا هو مشروع الخدمة. يحتوي على تنفيذ الخدمة بدون حالة.

تنفيذ الخدمة

افتح ملف HelloWorldStateless.cs في مشروع الخدمة. في Service Fabric، يمكن للخدمة تشغيل أي منطق تسلسل العمل. توفر واجهة برمجة تطبيقات الخدمة نقطتي دخول للتعليمة البرمجية الخاصة بك:

  • طريقة نقطة دخول مفتوحة، تسمى RunAsync، ومنها يمكنك البدء في تنفيذ أي أحمال عمل بما في ذلك أحمال عمل الحوسبة طويلة الأمد.
protected override async Task RunAsync(CancellationToken cancellationToken)
{
    ...
}
  • نقطة دخول اتصال يمكنك منها توصيل مكدس الاتصالات الذي تختاره، مثل ASP.NET Core. ومن هنا يمكنك البدء في تلقي الطلبات من المستخدمين والخدمات الأخرى.
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    ...
}

في هذا البرنامج التعليمي، سنركز على طريقة نقطة الدخول RunAsync(). هنا يمكنك البدء فورًا في تشغيل التعليمات البرمجية الخاصة بك. يتضمن قالب المشروع عينة تنفيذ من RunAsync() تُزيد من عدد المتداول.

ملاحظة

لتفاصيل أكثر حول كيفية العمل مع مكدس اتصالات، راجع اتصال الخدمة باستخدام ASP.NET Core

RunAsync

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    // TODO: Replace the following sample code with your own logic
    //       or remove this RunAsync override if it's not needed in your service.

    long iterations = 0;

    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();

        ServiceEventSource.Current.ServiceMessage(this.Context, "Working-{0}", ++iterations);

        await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
    }
}

يستدعي النظام الأساسي هذه الطريقة عند وضع مثيل خدمة في حالة الجاهزية للتنفيذ. بالنسبة لنوع الخدمة بدون حالة، هذا يعني ببساطة عند فتح مثيل الخدمة. يتم توفير رمز إلغاء مميز للتنسيق عند الحاجة إلى إغلاق مثيل الخدمة الخاص بك. في Service Fabric، يمكن أن تحدث دورة الفتح/الإغلاق هذه لمثيل الخدمة عدة مرات على مدار عمر الخدمة ككل. يمكن أن يحدث هذا لأسباب مختلفة، منها:

  • أن النظام يقوم بنقل مثيلات الخدمة الخاصة بك لتحقيق التوازن بين الموارد.
  • ومنها حودث أخطاء في التعليمة البرمجية الخاصة بك.
  • ترقية التطبيق أو النظام.
  • حدوث انقطاع في الأجهزة الأساسية.

تتم إدارة هذا التنسيق بواسطة النظام للحفاظ على توافر خدمتك بشكل كبير ومتوازن بشكل سليم.

RunAsync() يجب ألا تمنع بشكل متزامن. يجب أن يؤدي تنفيذ RunAsync إلى إرجاع مهمة أو الانتظار في أي عمليات طويلة الأمد أو عمليات حظر للسماح باستمرار وقت التشغيل. لاحظ أن التكرار الحلقي while(true) في المثال السابق، استخدم فيه مهمة الإرجاع await Task.Delay(). إذا كان يجب حظر عبء العمل الخاص بك بشكل متزامن، فيجب عليك جدولة مهمة جديدة مع Task.Run() عند RunAsync التنفيذ.

إلغاء عبء العمل الخاص بك هو جهد تعاوني يتم تنسيقه بواسطة رمز الإلغاء المقدم. سينتظر النظام حتى تنتهي مهمتك (باكتمال أو إلغاء أو خطأ ) قبل المضي قدما. من المهم الانتباه لرمز الإلغاء المميز، وإنهاء أي عمل، والخروج من RunAsync() بأسرع وقت ممكن عندما يطلب النظام الإلغاء.

في مثال الخدمة بدون حالة هذا، يتم تخزين العدد في متغير محلي. ولكن نظرًا لأن هذه الخدمة بدون حالة، فإن القيمة المخزنة موجودة فقط لدورة الحياة الحالية لمثيل الخدمة الخاص بها. عند نقل الخدمة أو إعادة تشغيلها، يتم فقدان القيمة.

إنشاء خدمة ذات حالة

تقدم Service Fabric نوعًا جديدًا من الخدمات التي تتسم بالحالة. يمكن للخدمة ذات الحالة الحفاظ على الحالة بشكل موثوق داخل الخدمة نفسها، في موقع مشترك بنفس الرمز المميز المستخدم. يتم إتاحة الحالة بشكل كبير بواسطة Service Fabric دون الحاجة إلى إبقاء الحالة في متجر خارجي.

لتحويل قيمة عداد من بدون حالة إلى حالة إتاحة عالية ومستمرة، حتى عند نقل الخدمة أو إعادة تشغيلها، تحتاج إلى خدمة ذات حالة.

في نفس تطبيق HelloWorld، يمكنك إضافة خدمة جديدة عن طريق النقر بزر الماوس الأيمن فوق مراجع الخدمات في مشروع التطبيق وتحديد إضافة ->خدمة Service Fabric جديدة.

إضافة خدمة إلى تطبيق Service Fabric الخاص بك

حدد .NET Core 2.0 -> خدمة ذات حالة وقم بتسميتها HelloWorldStateful. انقر فوق موافق.

استخدام مربع الحوار مشروع جديد لإنشاء خدمة جديدة ذات حالة Service Fabric

يجب أن يحتوي طلبك الآن على خدمتين: خدمة بدون حالة HelloWorldStateless وخدمة بحالة HelloWorldStateful.

تحتوي الخدمة ذات الحالة على نفس نقاط الدخول مثل الخدمة بدون حالة. الفرق الرئيسي هو توافر مزود الحالة الذي يمكنه تخزين الحالة بشكل موثوق. يتوفر Service Fabric مع مزود حالة يسمى اتصالات موثوق بها، والذي يتيح لك إنشاء بنية بيانات متماثلة من خلال مدير الحالة الموثوق. تستخدم الخدمة ذات الحالة الموثوقة موفر الحالة بشكل افتراضي.

افتحHelloWorldStateful.cs في HelloWorldStateful والذي يحتوي على أسلوب RunAsync التالي:

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    // TODO: Replace the following sample code with your own logic
    //       or remove this RunAsync override if it's not needed in your service.

    var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, long>>("myDictionary");

    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();

        using (var tx = this.StateManager.CreateTransaction())
        {
            var result = await myDictionary.TryGetValueAsync(tx, "Counter");

            ServiceEventSource.Current.ServiceMessage(this.Context, "Current Counter Value: {0}",
                result.HasValue ? result.Value.ToString() : "Value does not exist.");

            await myDictionary.AddOrUpdateAsync(tx, "Counter", 0, (key, value) => ++value);

            // If an exception is thrown before calling CommitAsync, the transaction aborts, all changes are
            // discarded, and nothing is saved to the secondary replicas.
            await tx.CommitAsync();
        }

        await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
    }

RunAsync

RunAsync() تعمل بنفس الطريقة في الخدمات ذات الحالة والخدمات بدون حالة. ومع ذلك، في خدمة الحالة، تقوم المنصة بعمل إضافي نيابة عنك قبل أن تنفذ RunAsync(). يمكن أن يشمل هذا العمل التأكد من أن مدير الحالة الموثوق به والمجموعات الموثوقة جاهزة للاستخدام.

المجموعات الموثوقة ومدير الحالة الموثوق به

var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, long>>("myDictionary");

IReliableDictionary هو تطبيق قاموس يمكنك استخدامه لتخزين الحالة بشكل موثوق في الخدمة. باستخدام Service Fabric والمجموعات الموثوقة، يمكنك تخزين البيانات مباشرة في خدمتك دون الحاجة إلى مخزن خارجي ثابت. المجموعات الموثوقة تجعل بياناتك متاحة بشكل أكبر. يقوم Service Fabric بتنفيذ هذه الخطوة من خلال إنشاء وإدارة نسخ متماثلة متعددة من الخدمة الخاصة بك. كما يوفر واجهة برمجة تطبيقات تقوم بتبسيط تعقيدات إدارة تلك النسخ المتماثلة والتنقل بين حالاتها.

يمكن للمجموعات الموثوقة تخزين أي نوع .NET، بما في ذلك الأنواع المخصصة الخاصة بك، مع بعض المحاذير:

  • يتيح Service Fabric حالتك بشكل كبير من خلال النسخ المتماثل للحالة عبر العقد، وتقوم المجموعات الموثوقة بتخزين بياناتك على قرص محلي على كل نسخة متماثلة. هذا يعني أن كل ما يتم تخزينه في مجموعات موثوقة يجب أن يكون قابلا للتسلسل. بشكل افتراضي، تستخدم "المجموعات الموثوقة" DataContract للتسلسل، لذلك من المهم التأكد من أن أنواعك مدعومة بواسطة "متسلسل عقد البيانات عند استخدام المتسلسل الافتراضي.

  • يتم نسخ الكائنات لتوفير قابلية وصول عالية عند تنفيذ المعاملات على المجموعات الموثوقة. يتم الاحتفاظ بالعناصر المخزنة في مجموعات موثوقة في الذاكرة المحلية في خدمتك. هذا يعني أن لديك مرجع محلي إلى العنصر.

    من المهم عدم تغيير المثيلات المحلية لتلك العناصر دون إجراء عملية تحديث على المجموعة الموثوقة في العملية. وذلك لأن التغييرات التي تطرأ على المثيلات المحلية للعناصر لن يتم نسخها تلقائيًا. يجب إعادة إدراج العنصر مرة أخرى في القاموس أو استخدام أحد أساليب التحديث في القاموس.

يدير مدير الحالة الموثوق به مجموعات موثوقة نيابة عنك. يمكنك ببساطة أن تطلب من مدير الحالة الموثوق به مجموعة موثوقة بالاسم في أي وقت وفي أي مكان في خدمتك. يضمن لك مدير الحالة الموثوق به الحصول على مرجع مرة أخرى. لا نوصي بحفظ المراجع إلى مثيلات تجميع موثوقة في متغيرات أو خصائص أعضاء الفئة. يجب توخي الحذر الشديد لضمان تعيين المرجع إلى مثيل في جميع الأوقات في دورة حياة الخدمة. يتعامل مدير الحالة الموثوق به بالنيابة عنك، وهو محسن للزيارات المتكررة.

المعاملات والعمليات غير المتزامنة

using (ITransaction tx = this.StateManager.CreateTransaction())
{
    var result = await myDictionary.TryGetValueAsync(tx, "Counter-1");

    await myDictionary.AddOrUpdateAsync(tx, "Counter-1", 0, (k, v) => ++v);

    await tx.CommitAsync();
}

تحتوي المجموعات الموثوقة على العديد من العمليات نفسها التي تقوم بها نظيراتهاSystem.Collections.Generic و System.Collections.Concurrent، باستثناء الاستعلام المتكامل للغة (LINQ). تتم العمليات على المجموعات الموثوقة بدون تزامن. وذلك لأن عمليات الكتابة باستخدام مجموعات موثوقة تقوم بتنفيذ عمليات إدخال/إخراج لنسخ البيانات واستمرارها على القرص.

عمليات المجموعات الموثوقة هي عملية معاملات، ولذلك يمكنك الحفاظ على اتساق الحالة عبر العديد من المجموعات والعمليات الموثوقة. على سبيل المثال، يمكنك إلغاء وضع عنصر عمل من قائمة انتظار موثوق بها، وتنفيذ عملية عليه، وحفظ النتيجة في قاموس موثوق، وكل ذلك ضمن معاملة واحدة. يتم التعامل مع هذا على أنه عملية تلقائية، ويضمن إما أن العملية بأكملها ستنجح أو أن العملية بأكملها ستعود للحالة السابقة. في حالة حدوث خطأ بعد حذف العنصر من قائمة الانتظار ولكن قبل حفظ النتيجة، يتم إرجاع المعاملة بأكملها إلى حالتها السابقة ويبقى العنصر في قائمة الانتظار للمعالجة.

شغّل التطبيق

نعود الآن إلى تطبيق HelloWorld. يمكنك الآن إنشاء خدماتك وتوزيعها. عند الضغط على F5، سيتم إنشاء التطبيق الخاص بك وتوزيعه على مجموعتك المحلية.

بعد بدء تشغيل الخدمات، يمكنك عرض تتبع الأحداث Windows (ETW) التي تم إنشاؤها في نافذة أحداث تشخيصية. لاحظ أن الأحداث المعروضة هي من نوعي الخدمات ذات حالة وبدون حالة في التطبيق. يمكنك إيقاف دفق البيانات مؤقتا بالنقر فوق الزر إيقاف مؤقت. يمكنك بعد ذلك فحص تفاصيل الرسالة عن طريق توسيع تلك الرسالة.

ملاحظة

قبل تشغيل التطبيق، تأكد من تشغيل نظام مجموعة تطوير محلي. راجع دليل بدء الاستخدام للحصول على معلومات حول إعداد بيئتك المحلية.

عرض الأحداث التشخيصية في Visual Studio

الخطوات التالية

تصحيح أخطاء تطبيق Service Fabric الخاص بك في Visual Studio

البدء: خدمات واجهة برمجة تطبيقات ويب Fabric Service مع الاستضافة الذاتية لـ OWIN

مزيد من المعلومات حول المجموعات الموثوقة

نشر تطبيق

ترقية التطبيق

مرجع المطور للخدمات الموثوقة