سؤال

أنا أعلم ذلك مع Network Load Balancing و Failover Clusteringيمكننا أن نجعل الخدمات السلبية متاح للغاية. لكن ماذا عن التطبيقات النشطة?

مثال: يسترجع أحد تطبيقاتي بعض المحتوى من مورد خارجي في فاصل ثابت. لقد تخيلت السيناريوهات التالية:

  1. قم بتشغيله في جهاز واحد. المشكلة: إذا سقطت هذه الحالة ، فلن يتم استرداد المحتوى
  2. قم بتشغيله في كل جهاز من الكتلة. المشكلة: سيتم استرداد المحتوى عدة مرات
  3. اجعلها في كل جهاز من الكتلة ، ولكن قم بتشغيلها فقط في واحد منها. سيتعين على كل مثيل التحقق من نوع من الموارد الشائعة لتحديد ما إذا كان دوره للقيام بالمهمة أم لا.

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

هل هذا هو الحل الأمثل؟ كيف يفعل الناس هذا عادة؟

بالمناسبة ، يتم تشغيل تطبيق C# .NET WCF على Windows Server 2008

هل كانت مفيدة؟

المحلول

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

أنا على جانب Java Ee من العالم ، لذا يمكنني مساعدتك في تفاصيل الترميز

نصائح أخرى

لقد قمت بتطبيق شيء مشابه مرة واحدة باستخدام الحل رقم 3 الخاص بك.

إنشاء جدول يسمى شيء مثل resource_lock, ، مع عمود (على سبيل المثال locking_key) الذي سيحتوي على مفتاح قفل.

ثم في كل فاصل زمني ، كل حالة تطبيقك سوف:

  1. قم بتشغيل استعلام مثل "update resource_lock set resource_key = 1 where resource_key is null'. (يمكنك بالطبع أيضًا إدراج معرف خاص بالخادم أو طابع زمني وما إلى ذلك)
  2. إذا تم تحديث 0 صفوف: لا شيء - مثيل تطبيق آخر يجلب بالفعل المورد.
  3. إذا تم تحديث صف واحد: جلب المورد وتعيين locking_key ارجع الى null.

هناك مزايا مع هذا:

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

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

  • هل يجب أن تكمل المهمة بنجاح؟
  • إذا لم تكتمل/لم تكمل المهمة بنجاح ، "من يحتاج إلى معرفته ونوع الإجراءات التي يجب تنفيذها؟
  • ما هو السلوك إذا لم تكتمل المهمة عندما يحين الوقت لتشغيل المهمة مرة أخرى؟ هل يجب أن تعمل أم لا؟
  • ما مدى أهمية أن تعمل الوظائف في الفاصل الزمني المحدد؟ إذا كان الفاصل الزمني كل 5 دقائق ، فهل يجب أن يكون كل 5 دقائق أو هل يمكن أن تعمل المهمة بعد 5 دقائق و 10 ثوان؟

الخطوة الأولى هي الإجابة على كيفية جدولة المهمة الدورية. أحد الخيارات هو مهمة مجدولة Windows ، لكن هذه ليست متاحة بطبيعتها بشكل كبير ولكن قد يكون من الممكن التنفيذ حول ذلك. إذا كنت تستخدم SQL Server ، فسيتمثل البديل الآخر في استخدام وكيل SQL Server كجدول لأنه سيخفق كجزء من SQL Server.

الخطوة التالية لتحديد هي كيفية استدعاء تطبيق WCF. سيكون الخيار الأسهل هو تشغيل وظيفة لاستدعاء خدمة WCF من خلال عنوان IP NLB. يمكن اعتبار ذلك أمرًا لا يوجد ما إذا كان خادم قاعدة البيانات (أو خادم آخر في تلك المنطقة) يتصل بمنطقة التطبيق (بالطبع هناك دائمًا استثناءات مثل MSDTC).

خيار آخر هو استخدام نموذج قائمة الانتظار. سيكون هذا هو الأكثر موثوقية في معظم المواقف. على سبيل المثال ، يمكن لـ SQL Server Agent تنفيذ إجراء مخزن لإدخال سجل في جدول قائمة انتظار. ثم في كل خادم تطبيق ، يمكن للخدمة استطلاعًا للبحث عن سجل في قائمة الانتظار للمعالجة. سيتم تسلسل الوصول إلى السجل في قائمة الانتظار بواسطة قاعدة البيانات بحيث يقوم الخادم الأول في تشغيل المهمة (وستستمر هذه المهمة مرة واحدة فقط).

اعتمادًا على إجابات الأسئلة الافتتاحية في هذه الإجابة ، قد تضطر إلى إضافة المزيد من معالجة الأخطاء. إذا كان استرجاع المورد الخارجي عادة ما يكون قصيرًا إلى حد ما ، فقد ترغب ببساطة في الحفاظ على سجل قائمة الانتظار مغلقًا بـ select for update وعندما تكتمل المهمة ، قم بتحديث الحالة (أو احذف السجل إذا كنت ترغب في ذلك). سيؤدي ذلك إلى منع مثيلات الخدمة الأخرى من معالجة السجل أثناء معالجته على خادم آخر ، وإذا حدث تصادم أثناء معالجة المعاملة ، فيجب إعادة ترحيل المعاملة ويمكن أن تلتقط خدمة أخرى في المجموعة السجل. (على الرغم من أنه يمكنك زيادة مهلة المعاملات طالما أنك تعتقد أنك تحتاج.)

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

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

من وجهة نظر البساطة ، فإن أسرع/أسهل طريقة لإنجاز ما تبحث عنه هي "جولة حول مجموعةك بحيث يتم تحديد جهاز (من خلال خدمة إدارة الكتلة أو بعضها). لمعالجة الطلب. لا تذهب طلبات العميل الفعلية مباشرة إلى الجهاز الذي يتولى ذلك ؛ وبدلاً من ذلك ، يشيرون إلى نقطة نهاية واحدة ، والتي تعمل كوكيل لتوزيع الطلبات الواردة على الآلات بناءً على التوفر والتحميل. لاقتباس الرابط الذي تم الإشارة إليه أدناه ،

يعد موازنة تحميل الشبكة وسيلة لتكوين مجموعة من الآلات بحيث تتناوب على الاستجابة للطلبات. يتم رؤيته بشكل شائع في مزارع الخادم: الآلات التي تم تكوينها بشكل متماثل تنشر الحمل لموقع ويب ، أو ربما مزرعة خادم طرفي. يمكنك أيضًا استخدامه في مزرعة جدار الحماية (ISA) ، ونقاط الوصول إلى VPN ، حقًا ، في أي وقت لديك حركة مرور TCP/IP أصبحت الكثير من التحميل لجهاز واحد ، لكنك لا تزال تريد أن تظهر كآلة واحدة لـ أغراض الوصول.

بالنسبة إلى أن التطبيق الخاص بك "نشط" ، فإن هذا الشرط لا يعامل في هذه المعادلة لأن ما إذا كان "نشطًا" أو "سلبيًا" ، فلا يزال التطبيق يقدم طلبًا إلى خوادمك.

توجد موازنات للحمل التجاري لخدمة طلبات على غرار HTTP ، بحيث قد يكون من المفيد النظر فيها ، ولكن مع ميزات موازنة التحميل لـ W2K8 ، قد يكون من الأفضل تقديمها إلى ذلك.

لمزيد من المعلومات حول كيفية تكوين ذلك في Win2K8 ، انظر هذه مقالة - سلعة.

هذه المقالة أكثر تقنية ويركز على استخدام NLB مع التبادل ، ولكن يجب أن تنطبق المبادئ على وضعك.

انظر هنا لمشاركة أخرى مفصلة لإعداد NLB والتكوين.

إذا فشلت ذلك ، قد يتم خدمتك جيدًا عن طريق البحث / النشر على ServerFault ، نظرًا لأن رمز التطبيق الخاص بك لا يكون (ولا ينبغي أن يكون) يدرك تمامًا أن NLB موجود.

تحرير: أضاف رابط آخر.

تحرير (الثاني): قام OP بتصحيح استنتاجي الخاطئ في المفهوم "النشط" مقابل "السلبي". إن إجابتي على ذلك تشبه إلى حد كبير إجابتي الأصلية ، باستثناء أن الخدمة "النشطة" (والتي ، نظرًا لكونك تستخدم WCF ، يمكن أن تكون خدمة Windows بسهولة) يمكن تقسيمها إلى جزأين: جزء المعالجة الفعلي ، و جزء الإدارة. سيعمل جزء الإدارة على خادم واحد ، ويعمل بمثابة موازن تحميل مستدير للخوادم الأخرى التي تقوم بالمعالجة الفعلية. إنه أكثر تعقيدًا قليلاً من السيناريو الأصلي ، لكنني أعتقد أنه سيوفر قدرًا كبيرًا من المرونة بالإضافة إلى تقديم فصل نظيف بين منطق المعالجة والإدارة.

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

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

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

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

يقوم Zookeeper بعمل حالة استخدام جيدة من الأقفال الموزعة. ZookeEper لديها Z-nodes التي تشبه الدليل مع البيانات.

حتى Netflix Armator لديه الكثير من الوصفات التي تم إجراؤها بالفعل والاستخدام. مثل: قائد الانتخابات ، قفل موزع وغيرها الكثير.

أعتقد أن لدينا عميل من Zookeeper لـ C#. يجب عليك بالتأكيد تجربة هذه الخيارات. #الخيار 3

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top