نموذج استضافة Azure Service Fabric

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

قبل المضي قدمًا، تأكد من أنك تفهم المفاهيم والعلاقات المختلفة الموضحة في نموذج تطبيق في "تصميم الخدمة".

إشعار

في هذه المقالة، ما لم يذكر صراحة على أنه يعني شيئًا مختلفًا:

  • النسخة المتماثلة تشير إلى كل من نسخة متماثلة من خدمة ذات حالة ومثيل لخدمة عديمة الحالة.
  • CodePackage يُتعامل معه على أنه مكافئ لعملية ServiceHost التي تسجل ServiceType وتستضيف نسخًا متماثلة من خدمات ServiceType هذه.

لفهم نموذج الاستضافة، لنشرح مثالًا. لنفترض أن لدينا ApplicationType "MyAppType"، والذي يحتوي على ServiceType "MyServiceType". ServicePackage 'MyServicePackage' يُوفر "MyServiceType"، والتي تحتوي على CodePackage 'MyCodePackage'. "MyCodePackage" يُسجل ServiceType 'MyServiceType' عند تشغيله.

لنفترض أن لدينا مجموعة من ثلاث عقد، وننشئ نسيج تطبيق:/App1 من النوع "MyAppType". داخل هذا التطبيق fabric:/App1، نُنشئ خدمة fabric:/App1/ServiceA من النوع "MyServiceType". تحتوي هذه الخدمة على قسمين (على سبيل المثال، P1 و P2)، وثلاث نسخ متماثلة لكل قسم. يوضح الرسم التخطيطي التالي طريقة عرض هذا التطبيق حيث ينتهي به الأمر إلى التوزيع على عُقدة.

رسم تخطيطي يوضح طريقة عرض هذا التطبيق لأنه ينتهي بنشره على عقدة.

قامت "تصميم الخدمة" بتنشيط "MyServicePackage"، الذي بدأ "MyCodePackage"، والذي يستضيف نسخًا متماثلة من كلا القسمين. جميع العقد في نظام مجموعة لها نفس طريقة العرض، لأننا اخترنا عدد النسخ المتماثلة لكل قسم ليكون مساويًا لعدد العُقد في المجموعة. لننشئ خدمة أخرى، fabric:/App1/ServiceB، في التطبيق fabric:/App1. تحتوي هذه الخدمة على قسم واحد (على سبيل المثال، P3)، وثلاث نسخ متماثلة لكل قسم. يوضح الرسم التخطيطي التالي طريقة العرض الجديدة على العُقدة:

رسم تخطيطي يوضح طريقة العرض الجديدة على العقدة.

وضع "تصميم الخدمة" النسخة المتماثلة الجديدة للقسم P3 للخدمة fabric:/App1/ServiceB في التنشيط الحالي لـ "MyServicePackage". الآن. لننشئ تطبيق آخر fabric:/App2 من النوع "MyAppType". داخل fabric:/App2، أنشئ fabric:/App2/ServiceA. تحتوي هذه الخدمة على قسمين (P4 و P5) وثلاث نسخ متماثلة لكل قسم. يوضح الرسم التخطيطي التالي طريقة عرض العُقدة الجديدة:

رسم تخطيطي يوضح طريقة عرض العقدة الجديدة.

يُفعّل "تصميم الخدمة" نسخة جديدة من "MyServicePackage"، والتي تبدأ نسخة جديدة من "MyCodePackage". تُوضع النسخ المتماثلة من كلا القسمين من خدمة fabric:/App2/ServiceA (P4 وP5) في هذه النسخة الجديدة "MyCodePackage".

نموذج العملية المشتركة

يصف القسم السابق نموذج الاستضافة الافتراضي الذي يوفره "تصميم الخدمة"، ويشار إليه باسم نموذج "العملية المشتركة". في هذا النموذج، بالنسبة لتطبيق معين، يتم تنشيط نسخة واحدة فقط من ServicePackage معين على عقدة (والتي تبدأ تشغيل كافة CodePackages الموجودة فيه). تُوضع كافة النسخ المتماثلة لكافة الخدمات الخاصة بـ ServiceType معين في CodePackage يسجل ServiceType هذا. بمعنى آخر، تشترك جميع النسخ المتماثلة لجميع الخدمات الموجودة على عُقدة من ServiceType معين في نفس العملية.

نموذج العملية الخاصّة

نموذج الاستضافة الآخر الذي يوفره "تصميم الخدمة" هو نموذج "العملية الخاصّة". في هذا النموذج، على عُقدة معينة، تتواجد كل نسخة متماثلة في عملية مخصصة خاصة بها. يُنشط "تصميم الخدمة" نسخة جديدة من ServicePackage (التي تبدأ تشغيل جميع CodePackages الموجودة فيه). تُوضع النسخ المتماثلة في CodePackage الذي سجّل ServiceType للخدمة التي تنتمي إليها النسخة المتماثلة.

إذا كنت تستخدم الإصدار 5.6 من "تصميم الخدمة" أو إصدار أحدث، فيمكنك اختيار نموذج "العملية الخاصّة" في وقت إنشاء خدمة (باستخدام PowerShell أو REST أو FabricClient). حدد ServicePackageActivationMode كـ "ExclusiveProcess".

PS C:\>New-ServiceFabricService -ApplicationName "fabric:/App1" -ServiceName "fabric:/App1/ServiceA" -ServiceTypeName "MyServiceType" -Stateless -PartitionSchemeSingleton -InstanceCount -1 -ServicePackageActivationMode "ExclusiveProcess"
var serviceDescription = new StatelessServiceDescription
{
    ApplicationName = new Uri("fabric:/App1"),
    ServiceName = new Uri("fabric:/App1/ServiceA"),
    ServiceTypeName = "MyServiceType",
    PartitionSchemeDescription = new SingletonPartitionSchemeDescription(),
    InstanceCount = -1,
    ServicePackageActivationMode = ServicePackageActivationMode.ExclusiveProcess
};

var fabricClient = new FabricClient(clusterEndpoints);
await fabricClient.ServiceManager.CreateServiceAsync(serviceDescription);

إذا كان لديك خدمة افتراضية في بيان التطبيق، يمكنك اختيار نموذج "العملية الخاصّة" عن طريق تحديد السمة ServicePackageActivationMode:

<DefaultServices>
  <Service Name="MyService" ServicePackageActivationMode="ExclusiveProcess">
    <StatelessService ServiceTypeName="MyServiceType" InstanceCount="1">
      <SingletonPartition/>
    </StatelessService>
  </Service>
</DefaultServices>

لننشئ خدمة أخرى، fabric:/App1/ServiceC، في التطبيق fabric:/App1. تحتوي هذه الخدمة على قسمين (على سبيل المثال، P6 و P7)، وثلاث نسخ متماثلة لكل قسم. يمكنك تعيين ServicePackageActivationMode إلى "ExclusiveProcess". يوضح الرسم التخطيطي التالي طريقة عرض جديدة على العُقدة:

رسم تخطيطي لعرض العقدة للتطبيق المنشور

كما ترى، نشّط "تصميم الخدمة" نسختين جديدتين من "MyServicePackage" (واحدة لكل نسخة متماثلة من القسم P6 و P7). وضع "تصميم الخدمة" كل نسخة متماثلة في نسختها المخصصة من CodePackage. عند استخدام نموذج "العملية الخاصّة" لتطبيق معين، يمكن أن تكون نسخ متعددة من ServicePackage معين نشطة على عُقدة. في المثال السابق، ثلاث نسخ من "MyServicePackage" نشطة لـ fabric:/App1. تحتوي كل نسخة من هذه النسخ النشطة من "MyServicePackage" على ServicePackageActivationId مرتبط بها. يحدد هذا المعرّف تلك النسخة داخل التطبيق fabric:/App1.

عند استخدام نموذج "العملية المشتركة" فقط لأحد التطبيقات، لا توجد سوى نسخة نشطة واحدة من ServicePackage على عُقدة. ServicePackageActivationId لهذا التنشيط من ServicePackage هو سلسلة فارغة. هذا هو الحال، على سبيل المثال، مع fabric:/App2.

إشعار

  • يتوافق نموذج استضافة "العملية المشتركة" مع ServicePackageActivationMode يساوي SharedProcess. هذا هو نموذج الاستضافة الافتراضي، ولا يلزم تحديد ServicePackageActivationMode في وقت إنشاء الخدمة.

  • يتوافق نموذج استضافة "العملية الخاصّة" مع ServicePackageActivationMode يساوي ExclusiveProcess. لاستخدام هذا الإعداد، يجب تحديده صراحة في وقت إنشاء الخدمة.

  • لعرض نموذج الاستضافة لخدمة ما، قم بالاستعلام عن وصف الخدمة، وانظر إلى قيمة ServicePackageActivationMode.

العمل باستخدام حزمة خدمة مُوزعة

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

يمكنك معرفة ServicePackageActivationId الخاص بحزمة خدمة مُوزعة عن طريق الاستعلام عن قائمة حزم الخدمات المُوزعة على عُقدة. عند الاستعلام عن أنواع الخدمات المُوزعة، والنسخ المتماثلة المُوزعة، وحزم التعليمات البرمجية المُوزعة على عقدة، تحتوي نتيجة الاستعلام أيضًا على ServicePackageActivationId الخاص بحزمة الخدمة المُوزعة الأصلية.

إشعار

  • ضمن نموذج استضافة "العملية المشتركة"، على عُقدة معينة لتطبيق معين، تُنشّط نسخة واحدة فقط من ServicePackage. يحتوي على ServicePackageActivationId يساوي سلسلة فارغة، ولا يلزم تحديده أثناء تنفيذ العمليات المتعلقة بحزمة الخدمة المُوزعة.

  • ضمن نموذج استضافة "العملية الخاصّة" في عُقدة معينة لتطبيق معين، يمكن أن تكون نسخة واحدة أو أكثر من ServicePackage نشطة. يحتوي كل تنشيط على ServicePackageActivationId غير فارغ، محدد أثناء تنفيذ العمليات المتعلقة بحزمة الخدمة المنشورة.

  • إذا حُذف ServicePackageActivationId، فسيُعيّن افتراضيًا إلى سلسلة فارغة. في حالة وجود حزمة خدمة مُوزعة تم تنشيطها ضمن نموذج "العملية المشتركة"، ستُنفذ العملية عليها. وإلا، فستفشل العملية.

  • لا تستفسر مرة واحدة، وخزّن ServicePackageActivationId مؤقتًا. يُنشأ المعرّف ديناميكيًا، ويمكن أن يتغير لأسباب مختلفة. قبل تنفيذ عملية تحتاج إلى ServicePackageActivationId، يجب أن تستعلم أولًا عن قائمة حزم الخدمات المُوزعة على عُقدة. ثم استخدم ServicePackageActivationId من نتيجة الاستعلام لتنفيذ العملية الأصلية.

تطبيقات الحاوية وملف الضيف القابل للتنفيذ

يتعامل "تصميم الخدمة" مع تطبيقات ملف الضيف القابل للتنفيذو الحاوية على أنها خدمات عديمة الحالة قائمة بذاتها. لا يوجد وقت تشغيل "تصميم الخدمة" في ServiceHost (عملية أو حاوية). نظرًا لأن هذه الخدمات مكتفية ذاتيًا، فإن عدد النسخ المتماثلة لكل ServiceHost لا ينطبق على هذه الخدمات. التكوين الأكثر شيوعًا المُستخدم مع هذه الخدمات هو قسم واحد، مع InstanceCount يساوي -1 (نسخة واحدة من التعليمة البرمجية للخدمة تعمل على كل عُقدة من نظام مجموعة).

يعد ServicePackageActivationMode الافتراضي لهذه الخدمات هو SharedProcess، وفي هذه الحالة يقوم "تصميم الخدمة" بتنشيط نسخة واحدة فقط من ServicePackage على عُقدة لتطبيق معين. هذا يعني أن نسخة واحدة فقط من التعليمة البرمجية للخدمة ستُشغل عُقدة. إذا كنت تريد تشغيل نسخ متعددة من التعليمات البرمجية للخدمة على عُقدة، فحدد ServicePackageActivationMode كـ ExclusiveProcess في وقت إنشاء الخدمة. على سبيل المثال، يمكنك القيام بذلك عند إنشاء خدمات متعددة (Service1 إلى ServiceN) من ServiceType (المحدد في ServiceManifest)، أو عندما تكون الخدمة متعددة الأقسام.

تغيير نموذج الاستضافة لخدمة موجودة

في الوقت الحالي، لا يمكنك تغيير نموذج الاستضافة لخدمة موجودة من "عملية مشتركة" إلى "عملية خاصّة" (أو العكس).

اختر من بين نماذج الاستضافة

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

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

اعتبارات نموذج العملية الخاصّة ونموذج التطبيق

بالنسبة لمعظم التطبيقات، يمكنك نمذجة التطبيق في "تصميم الخدمة" عن طريق الاحتفاظ بـ ServiceType واحد لكل ServicePackage.

في بعض الحالات، يسمح "تصميم الخدمة" أيضًا بأكثر من ServiceType واحد لكل ServicePackage (ويمكن لـ CodePackage واحد تسجيل أكثر من ServiceType واحد). فيما يلي بعض السيناريوهات التي يمكن أن تكون فيها هذه التكوينات مفيدة:

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

نموذج استضافة "العملية الخاصّة" غير متماسك مع نموذج تطبيق يحتوي على عِدة ServiceTypes لكل ServicePackage. يرجع ذلك إلى أن ServiceTypes المتعددة لكل ServicePackage مصممة لتحقيق مشاركة موارد أعلى بين النسخ المتماثلة، وتمكين كثافة نسخ متماثلة أعلى لكل عملية. يُصمم نموذج "العملية الخاصّة" لتحقيق نتائج مختلفة.

ضع في اعتبارك حالة ServiceTypes المتعددة لكل ServicePackage، مع وجود CodePackage مختلف يسجل كل ServiceType. لنفترض أن لدينا ServicePackage "MultiTypeServicePackage"، يحتوي على اثنين من CodePackages:

  • "MyCodePackageA" الذي يسجل ServiceType "MyServiceTypeA".
  • "MyCodePackageB" الذي يسجل ServiceType "MyServiceTypeB".

الآن، لنفترض أننا ننشئ تطبيقًا، fabric:/SpecialApp. داخل fabric:/SpecialApp، ننشئ الخدمتين التاليتين باستخدام نموذج "العملية الخاصّة":

  • الخدمة fabric:/SpecialApp/ServiceA من النوع "MyServiceTypeA"، مع قسمين (على سبيل المثال، P1 وP2) وثلاث نسخ متماثلة لكل قسم.
  • الخدمة fabric:/SpecialApp/ServiceB من النوع "MyServiceTypeB"، مع قسمين (P3 وP4) وثلاث نسخ متماثلة لكل قسم.

على عُقدة معينة، تحتوي كلتا الخدمتين على نسختين متماثلتين لكل منهما. نظرًا لأننا استخدمنا نموذج "العملية الخاصّة" لإنشاء الخدمات، يقوم "تصميم الخدمة" بتنشيط نسخة جديدة من "MyServicePackage" لكل نسخة متماثلة. يبدأ كل تفعيل لـ "MultiTypeServicePackage" نسخة من "MyCodePackageA" و "MyCodePackageB". مع ذلك، فإن واحد فقط من "MyCodePackageA" أو "MyCodePackageB" يستضيف النسخة المتماثلة التي تم تنشيط "MultiTypeServicePackage" لها. يوضح الرسم التخطيطي التالي طريقة عرض العُقدة:

رسم تخطيطي يوضح طريقة عرض العقدة.

في تنشيط "MultiTypeServicePackage" للنسخة المتماثلة من القسم P1 للخدمة fabric:/SpecialApp/ServiceA، يستضيف "MyCodePackageA" النسخة المتماثلة. "MyCodePackageB" قيد التشغيل. بالمثل، في تنشيط "MultiTypeServicePackage" للنسخة المتماثلة من القسم P3 للخدمة fabric:/SpecialApp/ServiceB، يستضيف "MyCodePackageB" النسخة المتماثلة. "MyCodePackageA" قيد التشغيل. بالتالي، كلما زاد عدد CodePackages (تسجيل أنواع مختلفة من ServiceTypes) لكل ServicePackage، زاد استخدام الموارد المتكررة.

مع ذلك، إذا أنشأنا الخدمتين fabric:/SpecialApp/ServiceA وfabric:/SpecialApp/ServiceB مع نموذج "العملية المشتركة"، فإن "تصميم الخدمة" يُنشط نسخة واحدة فقط من "MultiTypeServicePackage" للتطبيق fabric:/SpecialApp. يستضيف "MyCodePackageA" جميع النسخ المتماثلة للخدمة fabric:/SpecialApp/ServiceA. يستضيف "MyCodePackageB" جميع النسخ المتماثلة للخدمة fabric:/SpecialApp/ServiceB. يوضح الرسم التخطيطي التالي طريقة عرض العُقدة في هذا الإعداد:

رسم تخطيطي لعرض العقدة للتطبيق المنشور

في المثال السابق، قد تعتقد أنه إذا كان "MyCodePackageA" يسجل كلا من "MyServiceTypeA" و "MyServiceTypeB" ، ولا يوجد "MyCodePackageB"، فلن يوجد CodePackage متكرر قيد التشغيل. على الرغم من أن هذا صحيح، إلا أن نموذج التطبيق هذا لا يتوافق مع نموذج استضافة "العملية الخاصّة". إذا كان الهدف هو وضع كل نسخة متماثلة في عملية مخصصة خاصة بها، فلن تحتاج إلى تسجيل كلا ServiceTypes من نفس CodePackage. بدلًا من ذلك، يمكنك ببساطة وضع كل ServiceType في ServicePackage الخاص به.

الخدمات الموثوق بها والعمليات الفرعية لتشعُّب المستخدم

لا يدعم "تصميم الخدمة" الخدمات الموثوق بها وبالتالي العمليات الفرعية الموثوق بها لتشعُّب المستخدمين. مثال على سبب عدم دعمه هو عدم إمكانية استخدام CodePackageActivationContext لتسجيل عملية فرعية غير مدعومة، وتُرسل الرموز المميزة الإلغاء فقط إلى العمليات المسجلة، ما يؤدي إلى جميع أنواع المشكلات، مثل فشل الترقية، عندما لا تُغلق العمليات الفرعية بعد تلقي العملية الأصلية رمزًا مميزًا للإلغاء.

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

حزم تطبيق وجعله جاهزًا للتوزيع.

توزيع التطبيقات وإزالتها. توضح هذه المقالة كيفية استخدام PowerShell لإدارة مثيلات التطبيق.