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

هناك بالفعل نوعان من حلول الخدمات عديمة الجنسية. الأول هو خدمة تستمر في حالتها خارجيا، على سبيل المثال في قاعدة بيانات في قاعدة بيانات Azure SQL (مثل موقع ويب يخزن معلومات الجلسة وبياناتها). والثاني هو خدمات الحساب فقط (مثل الآلة الحاسبة أو الصورة المصغرة) التي لا تدير أي حالة مستمرة.
في كلتا الحالتين ، يعد تقسيم خدمة عديمة الجنسية سيناريو نادرا جدا - عادة ما يتم تحقيق قابلية التوسع والتوافر عن طريق إضافة المزيد من الحالات. المرة الوحيدة التي تريد فيها التفكير في أقسام متعددة لمثيلات الخدمة عديمة الجنسية هي عندما تحتاج إلى تلبية طلبات التوجيه الخاصة.
على سبيل المثال، ضع في اعتبارك حالة يجب فيها خدمة المستخدمين الذين لديهم معرفات في نطاق معين فقط من خلال مثيل خدمة معين. مثال آخر على الوقت الذي يمكنك فيه تقسيم خدمة عديمة الجنسية هو عندما يكون لديك واجهة خلفية مقسمة حقا (على سبيل المثال قاعدة بيانات مجزأة في قاعدة بيانات SQL) وتريد التحكم في مثيل الخدمة الذي يجب أن يكتب إلى شظية قاعدة البيانات - أو تنفيذ أعمال إعداد أخرى داخل الخدمة عديمة الجنسية التي تتطلب نفس معلومات التقسيم المستخدمة في الواجهة الخلفية. يمكن أيضا حل هذه الأنواع من السيناريوهات بطرق مختلفة ولا تتطلب بالضرورة تقسيم الخدمة.
يركز الجزء المتبقي من هذه الإرشادات التفصيلية على الخدمات الجيدة.
خدمات التقسيم النسيج
يجعل Service Fabric من السهل تطوير خدمات الحالة القابلة للتطوير من خلال تقديم طريقة من الدرجة الأولى لتقسيم الحالة (البيانات). من الناحية المفاهيمية ، يمكنك التفكير في قسم من خدمة الحالة كوحدة مقياس موثوقة للغاية من خلال النسخ المتماثلة التي يتم توزيعها وتوازنها عبر العقد في مجموعة.
يشير التقسيم في سياق خدمات Service Fabric المتطورة إلى عملية تحديد أن قسما معينا من أقسام الخدمة مسؤول عن جزء من الحالة الكاملة للخدمة. (كما ذكرنا من قبل ، فإن القسم عبارة عن مجموعة من النسخ المتماثلة). شيء عظيم حول Service Fabric هو أنه يضع الأقسام على عقد مختلفة. هذا يسمح لهم بالنمو إلى حد موارد العقدة. مع نمو احتياجات البيانات، تنمو الأقسام، ويقوم Service Fabric بإعادة توازن الأقسام عبر العقد. وهذا يضمن استمرار الاستخدام الفعال لموارد الأجهزة.
لإعطائك مثالا، لنفترض أنك تبدأ بمجموعة من 5 عقد وخدمة تم تكوينها بحيث تحتوي على 10 أقسام وهدف مكون من ثلاثة نسخ متماثلة. في هذه الحالة ، سيقوم Service Fabric بموازنة وتوزيع النسخ المتماثلة عبر المجموعة - وسينتهي بك الأمر بنسختين متماثلتين أساسيتين لكل عقدة. إذا كنت بحاجة الآن إلى توسيع نطاق المجموعة إلى 10 عقد ، فسيقوم Service Fabric بإعادة توازن النسخ المتماثلة الأساسية عبر جميع العقد العشر. وبالمثل ، إذا قمت بتقليص حجمها إلى 5 عقد ، فسيقوم Service Fabric بإعادة توازن جميع النسخ المتماثلة عبر العقد ال 5.
يوضح الشكل 2 توزيع 10 أقسام قبل وبعد قياس المجموعة.

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

نظرا لأن عدد سكان المدن يختلف اختلافا كبيرا ، فقد ينتهي بك الأمر ببعض الأقسام التي تحتوي على الكثير من البيانات (مثل سياتل) وأقسام أخرى ذات ولاية قليلة جدا (مثل كيركلاند). إذن ما هو تأثير وجود أقسام ذات كميات غير متساوية من الدولة؟
إذا فكرت في المثال مرة أخرى ، يمكنك بسهولة أن ترى أن القسم الذي يحمل الأصوات لسياتل سيحصل على حركة مرور أكثر من قسم كيركلاند. بشكل افتراضي، يتأكد Service Fabric من وجود نفس العدد تقريبا من النسخ المتماثلة الأساسية والثانوية على كل عقدة. لذلك قد ينتهي بك الأمر بعقد تحتوي على نسخ متماثلة تخدم المزيد من الزيارات وأخرى تخدم عددا أقل من الزيارات. يفضل أن ترغب في تجنب البقع الساخنة والباردة مثل هذه في مجموعة.
من أجل تجنب ذلك ، يجب عليك القيام بشيئين ، من وجهة نظر التقسيم:
- حاول تقسيم الحالة بحيث يتم توزيعها بالتساوي عبر جميع الأقسام.
- الإبلاغ عن الحمل من كل نسخة متماثلة للخدمة. (للحصول على معلومات حول كيفية القيام بذلك، راجع هذه المقالة حول المقاييس والتحميل). يوفر Service Fabric القدرة على الإبلاغ عن الحمل الذي تستهلكه الخدمات، مثل مقدار الذاكرة أو عدد السجلات. استنادا إلى المقاييس التي تم الإبلاغ عنها ، يكتشف Service Fabric أن بعض الأقسام تخدم أحمال أعلى من غيرها ويعيد توازن المجموعة عن طريق نقل النسخ المتماثلة إلى عقد أكثر ملاءمة ، بحيث لا يتم تحميل أي عقدة بشكل عام.
في بعض الأحيان ، لا يمكنك معرفة مقدار البيانات التي ستكون في قسم معين. لذا فإن التوصية العامة هي القيام بالأمرين معا - أولا ، من خلال اعتماد استراتيجية تقسيم تنشر البيانات بالتساوي عبر الأقسام وثانيا ، من خلال الإبلاغ عن الحمل. تمنع الطريقة الأولى المواقف الموضحة في مثال التصويت، بينما تساعد الطريقة الثانية على تخفيف الاختلافات المؤقتة في الوصول أو التحميل بمرور الوقت.
جانب آخر من تخطيط الأقسام هو اختيار العدد الصحيح من الأقسام لتبدأ. من منظور Service Fabric ، لا يوجد شيء يمنعك من البدء بعدد أكبر من الأقسام مما كان متوقعا للسيناريو الخاص بك. في الواقع ، على افتراض الحد الأقصى لعدد الأقسام هو نهج صالح.
في حالات نادرة ، قد ينتهي بك الأمر إلى الحاجة إلى أقسام أكثر مما اخترته في البداية. نظرا لأنه لا يمكنك تغيير عدد الأقسام بعد حدوثها ، ستحتاج إلى تطبيق بعض أساليب الأقسام المتقدمة ، مثل إنشاء مثيل خدمة جديد من نفس نوع الخدمة. ستحتاج أيضا إلى تنفيذ بعض المنطق من جانب العميل الذي يوجه الطلبات إلى مثيل الخدمة الصحيح ، استنادا إلى المعرفة من جانب العميل التي يجب الحفاظ عليها في التعليمات البرمجية للعميل.
هناك اعتبار آخر لتقسيم التخطيط وهو موارد الكمبيوتر المتاحة. نظرا لأن الحالة تحتاج إلى الوصول إليها وتخزينها ، فأنت ملزم بمتابعة:
- حدود النطاق الترددي للشبكة
- حدود ذاكرة النظام
- حدود تخزين القرص
إذن ماذا يحدث إذا واجهت قيودا على الموارد في مجموعة قيد التشغيل؟ الجواب هو أنه يمكنك ببساطة توسيع نطاق المجموعة لاستيعاب المتطلبات الجديدة.
يقدم دليل تخطيط السعة إرشادات حول كيفية تحديد عدد العقد التي تحتاجها مجموعتك.
بدء استخدام التقسيم
يوضح هذا القسم كيفية بدء تقسيم الخدمة.
تقدم Service Fabric خيارا من ثلاثة مخططات تقسيم:
- التقسيم المتراوح (المعروف باسم UniformInt64Partition).
- التقسيم المسماة. عادة ما تحتوي التطبيقات التي تستخدم هذا النموذج على بيانات يمكن تجميعها ضمن مجموعة محدودة. بعض الأمثلة الشائعة لحقول البيانات المستخدمة كمفاتيح تقسيم مسماة هي المناطق أو الرموز البريدية أو مجموعات العملاء أو حدود الأعمال الأخرى.
- تقسيم مفرد. عادة ما يتم استخدام أقسام Singleton عندما لا تتطلب الخدمة أي توجيه إضافي. على سبيل المثال، تستخدم الخدمات عديمة الجنسية نظام التقسيم هذا بشكل افتراضي.
مخططات التقسيم المسماة و Singleton هي أشكال خاصة من الأقسام المتراوحة. بشكل افتراضي، تستخدم القوالب Visual Studio ل Service Fabric التقسيم المتراوح، لأنه الأكثر شيوعا وفائدة. يركز الجزء المتبقي من هذه المقالة على مخطط التقسيم المتراوح.
مخطط التقسيم المتراوح
يستخدم هذا لتحديد نطاق عدد صحيح (يتم تحديده بواسطة مفتاح منخفض ومفتاح عال) وعدد من الأقسام (n). يقوم بإنشاء أقسام n ، كل منها مسؤول عن نطاق فرعي غير متداخل لنطاق مفتاح القسم الكلي. على سبيل المثال ، سيؤدي مخطط التقسيم المتراوح بمفتاح منخفض من 0 ، ومفتاح مرتفع من 99 ، وعدد 4 إلى إنشاء أربعة أقسام ، كما هو موضح أدناه.

النهج الشائع هو إنشاء تجزئة استنادا إلى مفتاح فريد داخل مجموعة البيانات. بعض الأمثلة الشائعة للمفاتيح هي رقم تعريف السيارة (VIN) أو معرف الموظف أو سلسلة فريدة. باستخدام هذا المفتاح الفريد ، ستقوم بعد ذلك بإنشاء رمز تجزئة ، معامل نطاق المفاتيح ، لاستخدامه كمفتاحك. يمكنك تحديد الحدود العلوية والسفلية لنطاق المفاتيح المسموح به.
حدد خوارزمية تجزئة
جزء مهم من التجزئة هو اختيار خوارزمية التجزئة الخاصة بك. هناك اعتبار هو ما إذا كان الهدف هو تجميع المفاتيح المتشابهة بالقرب من بعضها البعض (التجزئة الحساسة للموقع) - أو إذا كان ينبغي توزيع النشاط على نطاق واسع عبر جميع الأقسام (تجزئة التوزيع) ، وهو أكثر شيوعا.
تتمثل خصائص خوارزمية تجزئة التوزيع الجيدة في أنه من السهل حسابها ، ولديها عدد قليل من التصادمات ، وتوزع المفاتيح بالتساوي. مثال جيد على خوارزمية التجزئة الفعالة هي خوارزمية التجزئة FNV-1 .
مورد جيد لخيارات خوارزمية رمز التجزئة العامة هو صفحة ويكيبيديا على وظائف التجزئة.
إنشاء خدمة ذات حالة جيدة مع أقسام متعددة
دعنا ننشئ أول خدمة موثوقة ذات حالة مع أقسام متعددة. في هذا المثال ، ستقوم بإنشاء تطبيق بسيط للغاية حيث تريد تخزين جميع الأسماء الأخيرة التي تبدأ بنفس الحرف في نفس القسم.
قبل كتابة أي رمز ، تحتاج إلى التفكير في الأقسام ومفاتيح التقسيم. تحتاج إلى 26 قسما (واحد لكل حرف في الأبجدية) ، ولكن ماذا عن المفاتيح المنخفضة والعالية؟ نظرا لأننا نريد حرفيا أن يكون لدينا قسم واحد لكل حرف ، يمكننا استخدام 0 كمفتاح منخفض و 25 كمفتاح مرتفع ، حيث أن كل حرف هو مفتاحه الخاص.
ملاحظة
هذا سيناريو مبسط ، لأنه في الواقع سيكون التوزيع غير متساو. الأسماء الأخيرة التي تبدأ بالحروف "S" أو "M" أكثر شيوعا من تلك التي تبدأ ب "X" أو "Y".
افتح Visual Studio>ملفجديد>>Project.
في مربع الحوار Project جديد، اختر تطبيق Service Fabric.
أطلق على المشروع اسم "AlphabetPartitions".
في مربع الحوار إنشاء خدمة ، اختر خدمة الحالة وأطلق عليها اسم "Alphabet.Processing".
تعيين عدد الأقسام. افتح ملف Applicationmanifest.xml الموجود في المجلد ApplicationPackageRoot الخاص بمشروع AlphabetPartitions وقم بتحديث المعلمة Processing_PartitionCount إلى 26 كما هو موضح أدناه.
<Parameter Name="Processing_PartitionCount" DefaultValue="26" />تحتاج أيضا إلى تحديث خصائص LowKey و HighKey لعنصر StatefulService في ApplicationManifest.xml كما هو موضح أدناه.
<Service Name="Processing"> <StatefulService ServiceTypeName="ProcessingType" TargetReplicaSetSize="[Processing_TargetReplicaSetSize]" MinReplicaSetSize="[Processing_MinReplicaSetSize]"> <UniformInt64Partition PartitionCount="[Processing_PartitionCount]" LowKey="0" HighKey="25" /> </StatefulService> </Service>لكي يمكن الوصول إلى الخدمة ، افتح نقطة نهاية على منفذ عن طريق إضافة عنصر نقطة النهاية ServiceManifest.xml (الموجود في المجلد PackageRoot) لخدمة Alphabet.Processing كما هو موضح أدناه:
<Endpoint Name="ProcessingServiceEndpoint" Port="8089" Protocol="http" Type="Internal" />الآن يتم تكوين الخدمة للاستماع إلى نقطة نهاية داخلية مع 26 قسما.
بعد ذلك ، تحتاج إلى تجاوز
CreateServiceReplicaListeners()طريقة فئة المعالجة.ملاحظة
بالنسبة لهذه العينة ، نفترض أنك تستخدم HttpCommunicationListener بسيطا. لمزيد من المعلومات حول اتصالات الخدمة الموثوقة، راجع نموذج اتصال الخدمة الموثوقة.
النمط الموصى به لعنوان URL الذي تستمع إليه نسخة متماثلة هو التنسيق التالي:
{scheme}://{nodeIp}:{port}/{partitionid}/{replicaid}/{guid}. لذلك تريد تكوين مستمع الاتصال الخاص بك للاستماع إلى نقاط النهاية الصحيحة ومع هذا النمط.قد تتم استضافة نسخ متماثلة متعددة من هذه الخدمة على نفس الكمبيوتر، لذلك يجب أن يكون هذا العنوان فريدا للنسخة المتماثلة. هذا هو السبب في وجود معرف القسم + معرف النسخة المتماثلة في عنوان URL. يمكن ل HttpListener الاستماع على عناوين متعددة على نفس المنفذ طالما أن بادئة عنوان URL فريدة من نوعها.
يتوفر المعرف الفريد العمومي الإضافي لحالة متقدمة حيث تستمع النسخ المتماثلة الثانوية أيضا إلى طلبات القراءة فقط. عندما تكون هذه هي الحالة، فأنت تريد التأكد من استخدام عنوان فريد جديد عند الانتقال من أساسي إلى ثانوي لإجبار العملاء على إعادة حل العنوان. يتم استخدام "+" كعنوان هنا بحيث تستمع النسخة المتماثلة إلى جميع المضيفين المتاحين (IP و FQDN والمضيف المحلي وما إلى ذلك) يوضح الرمز أدناه مثالا.
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new[] { new ServiceReplicaListener(context => this.CreateInternalListener(context))}; } private ICommunicationListener CreateInternalListener(ServiceContext context) { EndpointResourceDescription internalEndpoint = context.CodePackageActivationContext.GetEndpoint("ProcessingServiceEndpoint"); string uriPrefix = String.Format( "{0}://+:{1}/{2}/{3}-{4}/", internalEndpoint.Protocol, internalEndpoint.Port, context.PartitionId, context.ReplicaOrInstanceId, Guid.NewGuid()); string nodeIP = FabricRuntime.GetNodeContext().IPAddressOrFQDN; string uriPublished = uriPrefix.Replace("+", nodeIP); return new HttpCommunicationListener(uriPrefix, uriPublished, this.ProcessInternalRequest); }تجدر الإشارة أيضا إلى أن عنوان URL المنشور يختلف قليلا عن بادئة عنوان URL للاستماع. يتم إعطاء عنوان URL للاستماع إلى HttpListener. عنوان URL المنشور هو عنوان URL الذي يتم نشره إلى خدمة تسمية نسيج الخدمة، والذي يستخدم لاكتشاف الخدمة. سيطلب العملاء هذا العنوان من خلال خدمة الاكتشاف هذه. يجب أن يكون العنوان الذي يحصل عليه العملاء IP الفعلي أو FQDN للعقدة من أجل الاتصال. لذلك تحتاج إلى استبدال "+" ب IP أو FQDN الخاص بالعقدة كما هو موضح أعلاه.
الخطوة الأخيرة هي إضافة منطق المعالجة إلى الخدمة كما هو موضح أدناه.
private async Task ProcessInternalRequest(HttpListenerContext context, CancellationToken cancelRequest) { string output = null; string user = context.Request.QueryString["lastname"].ToString(); try { output = await this.AddUserAsync(user); } catch (Exception ex) { output = ex.Message; } using (HttpListenerResponse response = context.Response) { if (output != null) { byte[] outBytes = Encoding.UTF8.GetBytes(output); response.OutputStream.Write(outBytes, 0, outBytes.Length); } } } private async Task<string> AddUserAsync(string user) { IReliableDictionary<String, String> dictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<String, String>>("dictionary"); using (ITransaction tx = this.StateManager.CreateTransaction()) { bool addResult = await dictionary.TryAddAsync(tx, user.ToUpperInvariant(), user); await tx.CommitAsync(); return String.Format( "User {0} {1}", user, addResult ? "successfully added" : "already exists"); } }ProcessInternalRequestيقرأ قيم معلمة سلسلة الاستعلام المستخدمة لاستدعاء القسم ويدعوAddUserAsyncإلى إضافة اسم العائلة إلى القاموسdictionaryالموثوق به .دعنا نضيف خدمة عديمة الجنسية إلى المشروع لمعرفة كيف يمكنك استدعاء قسم معين.
تعمل هذه الخدمة كواجهة ويب بسيطة تقبل اسم العائلة كمعلمة سلسلة استعلام ، وتحدد مفتاح القسم ، وترسله إلى خدمة Alphabet.Processing للمعالجة.
في مربع الحوار إنشاء خدمة ، اختر خدمة عديمة الحالة وأطلق عليها اسم "Alphabet.Web" كما هو موضح أدناه.
.قم بتحديث معلومات نقطة النهاية في ServiceManifest.xml خدمة Alphabet.WebApi لفتح منفذ كما هو موضح أدناه.
<Endpoint Name="WebApiServiceEndpoint" Protocol="http" Port="8081"/>تحتاج إلى إرجاع مجموعة من ServiceInstanceListeners في فئة ويب. مرة أخرى ، يمكنك اختيار تنفيذ HttpCommunicationListener بسيط.
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners() { return new[] {new ServiceInstanceListener(context => this.CreateInputListener(context))}; } private ICommunicationListener CreateInputListener(ServiceContext context) { // Service instance's URL is the node's IP & desired port EndpointResourceDescription inputEndpoint = context.CodePackageActivationContext.GetEndpoint("WebApiServiceEndpoint") string uriPrefix = String.Format("{0}://+:{1}/alphabetpartitions/", inputEndpoint.Protocol, inputEndpoint.Port); var uriPublished = uriPrefix.Replace("+", FabricRuntime.GetNodeContext().IPAddressOrFQDN); return new HttpCommunicationListener(uriPrefix, uriPublished, this.ProcessInputRequest); }الآن تحتاج إلى تنفيذ منطق المعالجة. يتصل
ProcessInputRequestHttpCommunicationListener عند وصول طلب. لذلك دعونا نمضي قدما ونضيف الرمز أدناه.private async Task ProcessInputRequest(HttpListenerContext context, CancellationToken cancelRequest) { String output = null; try { string lastname = context.Request.QueryString["lastname"]; char firstLetterOfLastName = lastname.First(); ServicePartitionKey partitionKey = new ServicePartitionKey(Char.ToUpper(firstLetterOfLastName) - 'A'); ResolvedServicePartition partition = await this.servicePartitionResolver.ResolveAsync(alphabetServiceUri, partitionKey, cancelRequest); ResolvedServiceEndpoint ep = partition.GetEndpoint(); JObject addresses = JObject.Parse(ep.Address); string primaryReplicaAddress = (string)addresses["Endpoints"].First(); UriBuilder primaryReplicaUriBuilder = new UriBuilder(primaryReplicaAddress); primaryReplicaUriBuilder.Query = "lastname=" + lastname; string result = await this.httpClient.GetStringAsync(primaryReplicaUriBuilder.Uri); output = String.Format( "Result: {0}. <p>Partition key: '{1}' generated from the first letter '{2}' of input value '{3}'. <br>Processing service partition ID: {4}. <br>Processing service replica address: {5}", result, partitionKey, firstLetterOfLastName, lastname, partition.Info.Id, primaryReplicaAddress); } catch (Exception ex) { output = ex.Message; } using (var response = context.Response) { if (output != null) { output = output + "added to Partition: " + primaryReplicaAddress; byte[] outBytes = Encoding.UTF8.GetBytes(output); response.OutputStream.Write(outBytes, 0, outBytes.Length); } } }دعونا نسير من خلال ذلك خطوة بخطوة. يقرأ الرمز الحرف الأول من معلمة
lastnameسلسلة الاستعلام في حرف. بعد ذلك ، يحدد مفتاح القسم لهذا الحرف عن طريق طرح القيمة السداسية العشرية منAالقيمة السداسية العشرية للحرف الأول للأسماء الأخيرة.string lastname = context.Request.QueryString["lastname"]; char firstLetterOfLastName = lastname.First(); ServicePartitionKey partitionKey = new ServicePartitionKey(Char.ToUpper(firstLetterOfLastName) - 'A');تذكر ، على سبيل المثال ، أننا نستخدم 26 قسما مع مفتاح قسم واحد لكل قسم. بعد ذلك ، نحصل على قسم
partitionالخدمة لهذا المفتاح باستخدام الطريقة الموجودةResolveAsyncعلىservicePartitionResolverالكائن.servicePartitionResolverيتم تعريفه على أنهprivate readonly ServicePartitionResolver servicePartitionResolver = ServicePartitionResolver.GetDefault();ResolveAsyncتأخذ هذه الطريقة عنوان URI للخدمة ومفتاح القسم ورمز الإلغاء المميز كمعلمات. خدمة URI لخدمة المعالجة هيfabric:/AlphabetPartitions/Processing. بعد ذلك ، نحصل على نقطة نهاية القسم.ResolvedServiceEndpoint ep = partition.GetEndpoint()أخيرا ، نقوم بإنشاء عنوان URL لنقطة النهاية بالإضافة إلى سلسلة الاستعلام ونتصل بخدمة المعالجة.
JObject addresses = JObject.Parse(ep.Address); string primaryReplicaAddress = (string)addresses["Endpoints"].First(); UriBuilder primaryReplicaUriBuilder = new UriBuilder(primaryReplicaAddress); primaryReplicaUriBuilder.Query = "lastname=" + lastname; string result = await this.httpClient.GetStringAsync(primaryReplicaUriBuilder.Uri);بمجرد الانتهاء من المعالجة ، نكتب الإخراج مرة أخرى.
الخطوة الأخيرة هي اختبار الخدمة. يستخدم Visual Studio معلمات التطبيق للنشر المحلي والسحابي. لاختبار الخدمة باستخدام 26 قسما محليا ، تحتاج إلى تحديث
Local.xmlالملف في مجلد ApplicationParameters الخاص بمشروع AlphabetPartitions كما هو موضح أدناه:<Parameters> <Parameter Name="Processing_PartitionCount" Value="26" /> <Parameter Name="WebApi_InstanceCount" Value="1" /> </Parameters>بمجرد الانتهاء من النشر، يمكنك التحقق من الخدمة وجميع أقسامها في مستكشف نسيج الخدمة.

في المستعرض، يمكنك اختبار منطق التقسيم عن طريق إدخال
http://localhost:8081/?lastname=somename. سترى أن كل اسم عائلة يبدأ بنفس الحرف يتم تخزينه في نفس القسم.
يتوفر الحل الكامل للرمز المستخدم في هذه المقالة هنا: https://github.com/Azure-Samples/service-fabric-dotnet-getting-started/tree/classic/Services/AlphabetPartitions.
الخطوات التالية
تعرف على المزيد حول خدمات نسيج الخدمة: