هل ترغب في تلقي إخطارات بالمحتوى الجديد؟
يمكن تصميم الخدمات من خلال تضمين جميع أنواع الموثوقية ومعدل المرونة، ولكن من أجل أن تكون الخدمات موثوق بها عمليًا، يجب أيضًا أن يتم التعامل مع حالات الفشل المتوقعة عند حدوثها. نقوم في شركة Amazon بتصميم الخدمات بحيث تكون قابلة للتطوير أفقيًا ومتكررة لأن الأجهزة مُصممة بحيث تتعرّض لإحدى حالات الفشل في نهاية المطاف. يتمتع أي محرك أقراص ثابت بعمر افتراضي متوقع كحد أقصى، على أن يكون أي جزء من البرنامج عرضة للتلف في وقت ما. وقد يبدو أن سلامة الخادم تكون ثنائية: إما أنه يعمل، أو لا يعمل مطلقًا ويبتعد عن مسار العمل المحدد له. وللأسف، لم يكن هذا هو الوضع. وجدنا أنه بدلاً من مجرد إيقاف التشغيل، قد يؤدي تعرض الخوادم للفشل إلى تعرّض النظام لتلف غير متوقع وأحيانًا غير متناسب. تكتشف عمليات التحقق من السلامة هذه الأنواع من المشكلات تلقائيًا، وتستجيب لها.
تستعرض هذه المقالة الطريقة التي نتّبعها لاستخدام عمليات التحقق من السلامة عند الكشف عن حالات الفشل في خادم واحد والتعامل مع هذه الحالات، وكذلك الأمور التي تنجم عن عدم استخدام عمليات التحقق من السلامة، وكيفية قيام الأنظمة التي تبالغ في ردة فعلها تجاه عمليات الفشل في التحقق من السلامة بتحويل المشكلات الصغيرة إلى حالات انقطاع تام للخدمة. كما نوفر رؤى من واقع الخبرة التي نتمتع بها في شركة Amazon بشأن توازن المفاضلات بين أنواع متعددة من عمليات تنفيذ التحقق من السلامة.
حالات فشل صغيرة لها آثار كبيرة
تم تشغيل التنبيهات الأخرى نظرًا لأن المراقبة تتضمن قياس معدلات الأخطاء وزمن الانتقال من نقاط متعددة في النظام. وبينما يمكن لهذه الأنواع من أنظمة المراقبة والعمليات التشغيلية أن تعمل كدعم بغرض تضمين المشكلة، يمكن لعمليات التحقق من السلامة المناسبة الحد بشكل كبير من آثار هذه الفئة من الأخطاء بالكامل من خلال الكشف عن حالات الفشل سريعًا والتعامل معها.
مفاضلات التحقق من السلامة
تُعد عمليات التحقق من السلامة طريقة يمكن اتباعها لطلب خدمة في خادم معين سواء كان يمكنه إجراء هذه الخدمة بنجاح أم لا. وتطرح موازنات الأحمال على كل خادم هذا السؤال دوريًا من أجل تحديد الخوادم الآمنة التي يمكن توجيه الزيارات إليها. وقد تطرح أية خدمة تفحص رسائل من قائمة انتظار أسئلة على نفسها بشأن ما إذا كانت سليمة أم لا قبل أن تقرر فحص المزيد من الأعمال الواردة من قائمة الانتظار. قد يطرح وكلاء المراقبة التي تعمل في كل الخوادم أو في أسطول مراقبة خارجي أسئلة على الخوادم بشأن ما إذا كانت سليمة أم لا بحيث يمكنها إصدار تنبيه أو التعامل تلقائيًا مع الخوادم التي تتعرّض للفشل.
كما رأينا في المثال المتعلق بالخطأ الذي تعرّض له موقع الويب الخاص بي، عندما يظل خادم غير سليم قيد الاستخدام، يمكنه أن يقلل بشكل غير متناسب من إتاحة الخدمة بالكامل. وعند استخدام أسطول من عشرات الخوادم، فإن وجود خادم واحد سيئ يعني أن نسبة إتاحة الأسطول قد تصل إلى 90% أو أقل. أصبحت الأمور أسوأ، حيث تمنح بعض لوغاريتمات موازنة الأحمال، مثل "أقل الطلبات"، مزيدًا من العمل إلى الخادم الأسرع. وعندما يتعرّض أحد الخوادم للفشل، فإنه يبدأ غالبًا بأن يعرّض الطلبات للفشل سريعًا وينشئ "فجوة سوداء" في أسطول الخدمة من خلال جذب المزيد من الطلبات مقارنة بالخوادم السليمة. ففي بعض الحالات، نضيف حماية أخرى بغرض تجنب حدوث الفجوات السوداء من خلال تباطؤ الطلبات التي تعرّضت للفشل من أجل مطابقة متوسط زمن انتقال الطلبات الناجحة. ومع ذلك، توجد سيناريوهات أخرى، مثل تلك التي تحدث عند استخدام أدوات فحص قائمة الانتظار بحيث يكون من الصعب جدًا التغلب على هذه المشكلة. فعلى سبيل المثال، إذا كانت أداة فحص قائمة الانتظار تفحص رسائل بالسرعة نفسها المُستخدمة عند تلقيها، فسيصبح الخادم الذي تعرّض للفشل فجوة سوداء أيضًا. وعند استخدام هذه المجموعة المتنوعة من البيئات بغرض توزيع العمل، تختلف الطريقة التي نتّبعها عند حماية خادم تعرّض للفشل جزئيًا من نظام لآخر.
نجد أن الخوادم تتعرّض للفشل بشكل مستقل ويرجع ذلك لبعض الأسباب، بما في ذلك الأقراص التي تصبح غير قابلة للكتابة عليها وتتسبب في تعرّض الطلبات للفشل على الفور، والساعات التي تنحرف فجأة وتتسبب في فشل مصادقة عمليات استدعاء التبعيات، والخوادم التي تفشل في استرداد مواد التشفير المحدّثة وتتسبب في فشل عمليتي التشفير وفك التشفير، وعمليات الدعم الحرجة التي تتعطل بسبب الأخطاء الخاصة بها، وعمليات التسرب للذاكرة، وحالات التوقف التام التي تعمل على تجميد المعالجة.
كما تفشل الخوادم لأسباب مترابطة تتسبب في تعرّض العديد منها أو جميعها الموجودة في أسطول للفشل معًا. وتتضمن الأسباب المترابطة حدوث مشكلات في الشبكة واسعة النطاق وانقطاع في التبعية المشتركة. سيجري التحقق المثالي من السلامة اختبارًا على كل جوانب سلامة الخادم والتطبيق، وربما يجري الآن تشغيل التحقق من صحة عمليات الدعم غير المهمة. ومع ذلك، تحدث المشكلات عندما يتعرّض التحقق من السلامة للفشل نتيجة لسبب غير مهم وعند ترابط هذا الفشل عبر كل الخوادم. إذا كانت عملية الأتمتة تزيل الخوادم من الخدمة عندما لا تزال تقوم بتنفيذ الأعمال المفيدة، فتتسبب عملية الأتمتة في حدوث ضرر أكبر من منفعة.
وتكمن الصعوبة في إجراء عمليات التحقق من السلامة في هذا التوتر الناشئ بين مزايا عمليات التحقق من السلامة بالكامل من جانب وتقليل حالات الفشل التي يتعرّض لها خادم واحد سريعًا، ومن جانب آخر بين الضرر الناجم عن فشل نتيجة إيجابية خاطئة عبر الأسطول بالكامل. ومن ثم، تتمثل أحد التحديات التي تتم مواجهتها عند إجراء التحقق من السلامة الصحيح في الحماية بعناية من النتائج الإيجابية الخاطئة. ويعني ذلك بشكل عام أنه يجب أن تتوقف عملية الأتمتة التي تحيط عمليات التحقق من السلامة عن توجيه الزيارات إلى خادم واحد سيئ، ولكن يجب أن تسمح بتوجيه الزيارات إذا كان الأسطول بالكامل يواجه مشكلة.
طرق لقياس السلامة
توجد العديد من الأمور التي يمكن أن تعرّض خادمًا للفشل، وتوجد العديد من الأماكن في أنظمتنا بحيث يمكننا قياس مدى سلامة الخادم. يمكن أن تبلغ بعض عمليات التحقق من السلامة بشكل نهائي عن تلف خادم معين بشكل مستقل، بينما تكون عمليات التحقق من السلامة الأخرى بجودة أقل وتبلغ عن النتائج الإيجابية الخاطئة في حالة حدوث حالات الفشل المرتبطة. ويصعب تنفيذ بعض عمليات التحقق من السلامة. ويتم تنفيذ عمليات التحقق من السلامة الأخرى عند إعداد خدمات مثل Amazon Elastic Compute Cloud (Amazon EC2) وElastic Load Balancing. ويتمتع كل نوع من أنواع التحقق من السلامة بنقاط قوة خاصة به.
تجري عمليات التحقق الحية اختبارًا على الاتصال الأساسي بالخدمة وعلى وجود عملية بواسطة الخادم. ويتم تنفيذها غالبًا من خلال موازن الأحمال أو وكيل مراقبة خارجي، كما أنها ليست على دراية بالتفاصيل المتعلقة بطريقة عمل التطبيق. يتم تضمين عمليات التحقق الحية في الخدمة، ولا تطلب مؤلف التطبيق من أجل تنفيذ أي إجراء. تتضمن بعض الأمثلة على عمليات التحقق الحية التي نستخدمها في شركة Amazon ما يلي:
• اختبارات تؤكد أن الخادم يعمل جيدًا بالمنفذ المتوقع ويقبل اتصالات TCP جديدة.
• اختبارات تجري طلبات HTTP أساسية وتضمن أن الخادم يستجيب بالتعليمة البرمجية للحالة 200.
• عمليات التحقق من الحالة في Amazon EC2 الذي يختبر أمورًا أساسية يلزم توفرها لأي نظام من أجل تشغيله، مثل قابلية الوصول للشبكة.
عمليات التحقق من السلامة المحلية تتجاوز عمليات التحقق الحية بغرض التحقق من أن التطبيق قد يكون قادرًا على أداء وظائفه. وتجري عمليات التحقق من السلامة هذه اختبارًا على الموارد غير المشتركة مع نظراء الخادم. لذلك، من غير المرجح أنها تتعرّض للفشل في العديد من الخوادم في الأسطول في الوقت نفسه. تجري عمليات التحقق من السلامة هذه اختبارًا على ما يلي:
• عدم القدرة على الكتابة في القرص أو القراءة منه—قد تعتقد أن الخدمة بلا حالة لا تطلب قرصًا قابلاً للكتابة عليه. ومع ذلك، ستستخدم خدماتنا في شركة Amazon الأقراص لإجراء أمور مثل مراقبة بيانات القياس غير المتزامنة وتسجيلها ونشرها.
• عمليات مهمة متعطلة أو تالفة—تحصل بعض الخدمات على طلبات باستخدام وكيل بالخادم (مشابه لـ NGINX) وتقوم بتنفيذ منطق الأعمال في عملية خادم أخرى. قد لا يجري التحقق الحي سوى اختبار ليتحقق مما إذا كانت عملية الوكيل قيد التشغيل أم لا. وقد تتم عملية التحقق من السلامة المحلية بداية من الوكيل إلى التطبيق بغرض التحقق من أنهما يعملان على تشغيل عملية التحقق والرد على الطلبات بشكل صحيح. والجدير بالذكر أنه في المثال المتعلق بموقع الويب الذي تمت الإشارة إليه في بداية المقال، كان التحقق من السلامة الحالي عميقًا بما يكفي لضمان أن عملية العرض كانت قيد التشغيل وتستجيب، ولكنه ليس عميقًا بما يكفي لضمان أنه كان يستجيب بشكل صحيح.
• عمليات الدعم المفقودة—قد تترك الأجهزة المضيفة التي تفقد البرامج الخفية للمراقبة الخاصة بها مشغلات "التعتيم الخفي" ولا تكون على دراية بمدى سلامة خدماتها. بينما تقوم عمليات الدعم الأخرى بتنفيذ سجلات استخدام القياس والفوترة أو بتلقي تحديثات بشأن بيانات الاعتماد. تضع الخوادم التي تستخدم عمليات الدعم التالفة الوظائف في خطر بشكل غير ملحوظ وبطرق يصعب اكتشافها.
تُعد عمليات التحقق من سلامة التبعية عملية فحص شاملة لقدرة التطبيق على التفاعل مع الأنظمة المجاورة. ويمكن لعمليات التحقق هذه بشكل مثالي اكتشاف المشكلات المحلية في الخادم، مثل بيانات الاعتماد منتهية الصلاحية والتي تمنعها من التفاعل مع التبعية. ولكن يمكن أن تتضمن أيضًا نتائج إيجابية خاطئة عند وجود مشكلات في التبعية نفسها. ونظرًا لوجود نتائج إيجابية خاطئة، يجب أن نتوخى الحذر بشأن الطريقة التي نتّبعها عند التفاعل مع حالات فشل التحقق من سلامة التبعية. قد تجري عمليات التحقق من سلامة التبعية اختبارًا على ما يلي:
• التكوين السيئ أو بيانات التعريف التالفة—إذا كانت العملية تبحث بشكل غير متزامن عن التحديثات المتعلقة ببيانات التعريف أو التكوين ولكن آلية التحديث تالفة بالخادم، فقد يصبح الخادم غير متزامن بشكل كبير مع نظرائه ويسيئ التصرف بطريقة غير متوقعة ولم تخضع للاختبار. ومع ذلك، عندما لا يعثر الخادم على تحديث لبعض الوقت، فإنه لا يعرف ما إذا كانت آلية التحديث تالفة أم لا أو ما إذا كان نظام التحديث المركزي قد توقف عن نشر التحديثات لكل الخوادم أم لا.
• عدم القدرة على الاتصال بالتبعيات أو الخوادم النظراء—يُعرف سلوك الشبكة الغريب بأنه يؤثر على قدرة المجموعة الفرعية للخوادم في الأسطول على الاتصال بالتبعيات دون التأثير على إمكانية إرسال الزيارات إلى هذا الخادم. كما يمكن أن تؤدي المشكلات في البرامج، مثل حالات التوقف التام أو الأخطاء في مجموعات الاتصالات، إلى عرقلة الاتصال بالشبكة.
• أخطاء البرامج غير المعتادة الأخرى والتي تطلب عملية استرداد—يمكن أن تؤدي حالات التوقف التام أو عمليات التسرب للذاكرة أو أخطاء تلف الحالة إلى قيام الخادم بإصدار أخطاء.
يبحث الاكتشاف غير المألوف في كل الخوادم الموجودة في الأسطول بغرض تحديد ما إذا كان الخادم يتصرف بشكل غريب مقارنة بنظرائه أم لا. ومن خلال تجميع بيانات المراقبة لكل خادم، يمكننا باستمرار مقارنة معدلات الأخطاء أو بيانات زمن الانتقال أو السمات الأخرى من أجل البحث عن خوادم غير مألوفة وإزالتها تلقائيًا من الخدمة. يمكن للاكتشاف غير المألوف البحث عن اختلافات في الأسطول والتي لا يمكن للخادم نفسه اكتشافها، مثل ما يلي:
• انحراف الساعة—خاصة عندما تكون الخوادم تحت تحميل عال، تُعرف الساعات بأنها تنحرف فجأة وبشكل كبير. تتطلب التدابير الأمنية مثل تلك التدابير المُستخدمة لتقييم الطلبات الموقّعة والمُرسلة إلى AWS ألا يتجاوز الوقت المحدد في ساعة العميل مدة خمس دقائق بالنسبة للوقت الفعلي. وإذا لم يكن كذلك، فستتعرّض الطلبات للفشل في خدمات AWS.
• التعليمة البرمجية القديمة—في حالة قطع اتصال الخادم عن الشبكة أو إيقاف تشغيله لفترة طويلة وبعد ذلك إعادة اتصاله، قد يقوم بتشغيل تعليمة برمجية قديمة على نحو خطير بحيث لا تتوافق مع بقية الأسطول.
• أوضاع الفشل غير المتوقعة—تتعرّض أحيانًا الخوادم للفشل بطريقة تؤدي إلى إرجاع أخطاء وتحديد الخطأ مثل العميل الخاص بها بدلاً من العملاء الآخرين (مثل HTTP 400 بدلاً من 500). قد تتباطأ الخوادم بدلاً من فشلها أو أنها قد تستجيب بشكل أسرع من نظرائها، وهي علامة تدل على أنها تؤدي إلى إرجاع استجابات خاطئة إلى الوسطاء لديها. يُعد الاكتشاف غير المألوف عملية التقاط شاملة رائعة خاصة بأوضاع الفشل غير المتوقعة.
وتوجد بعض الأمور التي يجب أن تنطبق على الاكتشاف غير المألوف لتشغيله عمليًا:
• يجب أن تقوم الخوادم تقريبًا بتنفيذ الأمر نفسه—في الحالات التي نقوم فيها صراحة بتوجيه أنواع مختلفة من الزيارات إلى أنواع مختلفة من الخوادم، قد لا تعمل الخوادم بالطريقة نفسها بشكل كاف لاكتشاف الأخطاء. ومع ذلك، في الحالات التي نستخدم فيها موازنات الأحمال لتوجيه الزيارات إلى الخوادم، فإنها تستجيب بطرق مشابهة.
• يجب أن تكون الأساطيل متجانسة نسبيًا—في الأساطيل التي تتضمن أنواع مثيلات مختلفة، قد تكون بعض المثيلات أبطأ من غيرها مما يمكن أن يؤدي إلى اكتشاف الخادم السيئ السلبي بالخطأ. وللتغلب على هذا السيناريو، فإننا ندمج أدوات القياس حسب نوع المثيل.
• يجب الإبلاغ عن الأخطاء أو الاختلافات الموجودة في السلوك—نظرًا لأننا نعتمد على الخوادم نفسها فيما يتعلق بالإبلاغ عن الأخطاء، ماذا يحدث عندما تكون أنظمة المراقبة تالفة أيضًا؟ لحسن الحظ، يُعد عميل الخدمة مكان رائع لإضافة الأدوات. تعمل موازنات الأحمال مثل Application Load Balancer على نشر سجلات الوصول التي تعرض الخادم الخلفي الذي يتم الاتصال به عند إجراء أي طلب ووقت الاستجابة وما إذا نجح الطلب أم تعرّض للفشل.
التعامل بأمان مع حالات فشل التحقق من السلامة
عندما يحدد الخادم أنه غير سليم، يتوفر إجراءان يمكن اتخاذهما. ففي الحالات الأكثر خطورة، يمكنه محليًا تحديد أنه لا يجب منحه أي عمل ويجب إيقاف استخدامه من خلال فشل التحقق من سلامة موازن الأحمال أو إيقاف فحص قائمة الانتظار. وتتمثل الطريقة الأخرى التي يمكن للخادم التفاعل فيها في إخطار السلطة المركزية بأنه يواجه مشكلة ويدع النظام المركزي يتخذ قراره بشأن التعامل مع المشكلة. ويمكن للنظام المركزي معالجة المشكلة بأمان دون جعل عملية الأتمتة توقف تشغيل الأسطول بالكامل.
كما توجد طرق متعددة يتم استخدامها لتنفيذ عمليات التحقق من الصحة والاستجابة لها. يتناول هذا القسم بعض الأنماط التي نستخدمها في شركة Amazon.
يمكن لبعض موازنات الأحمال أن تتصرف باعتبارها سلطة مركزية ذكية. وعندما يفشل خادم فردي في إجراء التحقق من السلامة، يتوقف موازن الأحمال عن إرسال زيارات إليه. ولكن عندما تفشل كل الخوادم في إجراء عمليات التحقق من السلامة في وقت واحد، يفشل فتح موازن الأحمال مما يسمح بتوجيه الزيارات إلى كل الخوادم. يمكننا استخدام موازنات الأحمال لدعم تنفيذ التحقق من سلامة التبعية بشكل آمن، ربما تتضمن موازن أحمال يستعلم عن البيانات ويتحقق منها بغرض ضمان أن عمليات الدعم غير المهمة تكون قيد التشغيل.
فعلى سبيل المثال، يفشل فتح AWS Network Load Balancer إذا لم يبلغ أي خادم عن أنه غير سليم. كما أنه يفشل بسبب عدم سلامة مناطق توافر الخدمات إذا كانت كل الخوادم في منطقة توافر الخدمات تبلغ عن أنه غير سليم. (لمزيد من المعلومات حول استخدام Network Load Balancer في عمليات التحقق من السلامة، راجع وثائق Elastic Load Balancing). كما يدعم Application Load Balancer الخاص بنا، مثل Amazon Route 53، فشل الفتح. (لمزيد من المعلومات حول تكوين عمليات التحقق من السلامة باستخدام Route 53، راجع وثائق Route 53).
عندما نعتمد على سلوك فشل الفتح، فإننا نتأكد من إجراء اختبار على أوضاع الفشل الخاصة بالتحقق من سلامة التبعية. فعلى سبيل المثال، يمكنك مراعاة خدمة بحيث تكون الخوادم متصلة بمخزن البيانات المشترك. وإذا أصبح مخزن البيانات هذا بطيئًا أو يستجيب بمعدل أخطاء بطيء، فقد تؤدي الخوادم أحيانًا إلى فشل عمليات التحقق من سلامة التبعية. وينجم عن هذا الشرط دخول الخوادم في الخدمة وخروجها منها، لكن دون تشغيل عملية فشل الفتح. يمثل التبرير واختبار عمليات فشل التبعيات جزئيًا باستخدام عمليات التحقق من السلامة هذه أهمية لتجنب حدوث موقف بحيث يمكن لأية عملية فشل التسبب في إجراء عمليات التحقق من السلامة مما يجعل الأمور أسوأ.
بينما يكون فشل الفتح سلوكًا مفيدًا، فنحن في شركة Amazon نميل إلى الشك في الأمور التي لا يمكننا تبريرها بالكامل أو اختبارها في كل المواقف. لم نتوصل حتى الآن إلى أداة عامة تؤكد أن عملية فشل الفتح ستعمل بالطريقة المتوقعة في كل أنواع التحميل الزائد أو حالات الفشل الجزئي أو حالات الفشل الرمادي في النظام أو في تبعيات هذا النظام. ونتيجة لهذا التقييد، تميل فِرق العمل في شركة Amazon إلى تقييد عمليات التحقق من سلامة موازن الأحمال التي تتم سريعًا بحيث تصبح عمليات تحقق من السلامة المحلية، وكذلك الاعتماد على الأنظمة المركزية بغرض التعامل بعناية مع عمليات التحقق من سلامة التبعية التي تتم بشكل أعمق. ولا يعني ذلك أننا لا نستخدم سلوك فشل الفتح أو نؤكد على أنه يعمل في حالات معينة. ولكن عندما يمكن للمنطق أن يعمل على عدد كبير من الخوادم سريعًا، فإننا نتوخى الحذر بشدة تجاه استخدام هذا المنطق.
عند السماح للخوادم بالتفاعل مع مشكلاتها الخاصة، قد يبدو ذلك المسار الأسرع والأبسط لإجراء عملية الاسترداد. ومع ذلك، فإنه يمثل أيضًا المسار الأخطر إذا كان الخادم مخطئًا بشأن سلامته أو لا يرى الصورة كاملة بشأن ما يحدث في الأسطول. عندما تتخذ كل الخوادم في الأسطول القرار الخاطئ نفسه في وقت واحد، قد يؤدي ذلك إلى حدوث حالات فشل متتالية في كل الخدمات المجاورة. وتمنحنا هذه المخاطرة عملية مفاضلة. وفي حالة وجود فجوة في التحقق من السلامة والمراقبة، يمكن للخادم الحد من إتاحة الخدمة إلى أن يتم اكتشاف المشكلة. ومع ذلك، يتجنب هذا السيناريو حدوث انقطاع تام في الخدمة بسبب سلوك التحقق من السلامة غير المتوقع في الأسطول بالكامل.
فيما يلي أفضل الممارسات التي نتّبعها عند تنفيذ عمليات التحقق من السلامة في حالة عدم وجود قاطع دائرة مضمّن:
• يمكن تكوين منتج العمل (موازن الأحمال، مؤشر فحص قائمة الانتظار) من أجل إجراء عمليات التحقق من السلامة الحية والمحلية. وتتوقف الخوادم عن العمل تلقائيًا من خلال موازن الأحمال فقط إذا كانت تواجه بعض المشكلات المحلية بالتأكيد بالنسبة لهذا الخادم، مثل قرص سيئ.
• يمكن تكوين أنظمة مراقبة خارجية أخرى من أجل إجراء عمليات التحقق من سلامة التبعية والاكتشاف غير المألوف. وقد تحاول هذه الأنظمة إنهاء المثيلات تلقائيًا أو تنبيه المشغّل أو التفاعل معه.
وعندما نصمم الأنظمة خصيصًا للتفاعل تلقائيًا مع حالات فشل التحقق من سلامة التبعية، يجب علينا التصميم بالقدر المناسب من الحد لمنع النظام التلقائي من اتخاذ إجراء صارم بشكل غير متوقع. تتمتع فِرق العمل في شركة Amazon والتي تشغّل خوادم ذات حالة خاصة مثل Amazon DynamoDB وAmazon S3 وAmazon Relational Database Service (Amazon RDS) بمتطلبات استدامة مهمة بشأن استبدال الخادم. كما أنها تتمتع بتقييد المعدل الذي يتسم بالحذر والتكرارات الحلقية لملاحظات التحكم بحيث تتوقف عملية الأتمتة ويبدأ التفاعل مع الأشخاص عند تجاوز الحدود. عندما ننشئ عملية الأتمتة هذه، يجب علينا التأكد من أنه يمكننا الملاحظة عندما يفشل الخادم في إجراء التحقق من سلامة التبعية. بالنسبة لبعض أدوات القياس، فإننا نعتمد على الخوادم بأنها تقوم بعملية الإبلاغ الذاتي عن حالاتها الفردية إلى نظام مراقبة مركزي. للتعويض عن الحالات التي يكون الخادم فيها تالفًا للغاية بحيث لا يكون قادرًا على الإبلاغ عن سلامته، يمكننا أيضًا الوصول إليها بفاعلية بغرض التحقق من سلامتها.
من المهم بالنسبة للخوادم وخاصة في حالات التحميل الزائد وضع عمليات التحقق من السلامة في الأولوية على العمل العادي. وفي هذه الحالة، يمكن أن يؤدي فشل عمليات التحقق من السلامة أو الاستجابة ببطء إلى جعل حالة انقطاع الطاقة السيئة تزداد سوءًا.
عندما يفشل الخادم في التحقق من سلامة موازن الأحمال، فإنه يطلب من موازن الأحمال التوقف عن العمل على الفور ولفترة زمنية قصيرة. عندما يفشل خادم واحد، فإنه لا يمثل أية مشكلة، ولكن في حالة تدفق الزيارات إلى الخدمة، فإن آخر شيء نريده هو تقليل حجم الخدمة. ويمكن أن يؤدي إيقاف تشغيل الخوادم أثناء التحميل الزائد إلى حدوث انخفاض سريع في الأداء. إن فرض زيادة معدل الزيارات على بقية الخوادم قد يجعلها محمّلة بشكل زائد ويؤدي إلى فشل التحقق من السلامة وتقليل حجم الأسطول بشكل أكبر.
لا تكمن المشكلة في أن الخوادم المحمّلة بشكل زائد تقوم بإرجاع أخطاء عندما تكون محمّلة بشكل زائد. ولكنها تكمن في الخوادم التي لا تستجيب لطلب اختبار الاتصال في موازن الأحمال في الوقت المناسب. ومع ذلك، يتم تكوين عمليات التحقق من سلامة موازن الأحمال من خلال مهلة الاتصال كما هو الحال في اتصالات الخدمات عن بُعد الأخرى. تكون الخوادم التي تم انقطاع الطاقة عنها بطيئة في الاستجابة ويرجع ذلك لبعض الأسباب التي تتضمن اتصال وحدة المعالجة المركزية بالأداء العالي أو دورات جامع البيانات المهملة التي تستغرق مدة طويلة أو ببساطة نفاد مؤشرات الترابط العاملة. يلزم تكوين الخدمات لاستبعاد الموارد بغرض الاستجابة لعمليات التحقق من السلامة في الوقت المناسب بدلاً من الاضطلاع بطلبات إضافية تتجاوز الحد الأقصى.
ولحسن الحظ، يتوفر بعض أفضل الممارسات المُستخدمة للتكوين المباشر والتي نتّبعها بغرض تجنب هذا النوع من الانخفاض السريع في الأداء. تعمل أدوات مثل iptables وبعض موازنات الأحمال على دعم مفهوم "الحد الأقصى لللاتصالات". وفي هذا الحالة، يعمل نظام التشغيل (أو موازن الأحمال) على تقييد عدد الاتصالات بالخادم بحيث لا تكون عملية الخادم مليئة بالطلبات المتزامنة التي قد تؤدي إلى إبطاء أدائه.
عندما يقدم الخدمة وكيل أو موازن أحمال يدعم الحد الأقصى للاتصالات، يبدو ذلك منطقيًا بحيث يجعل عدد مؤشرات الترابط العاملة في خادم HTTP تتطابق مع الحد الأقصى للاتصالات في الوكيل. ومع ذلك، قد تقوم عملية التكوين هذه بإعداد الخدمة الخاصة بالتدهور السريع في الأداء أثناء انقطاع الطاقة. تحتاج عمليات التحقق من سلامة الوكيل إلى الاتصالات أيضًا، ومن ثم من المهم جعل المجموعة العاملة في الخادم كبيرة بما يكفي لتناسب طلبات التحقق من السلامة الأخرى. علمًا بأن مؤشرات الترابط العاملة الخاملة تكون زهيدة الثمن، لذا فإننا نريد تكوين المزيد منها: في أي مكان من القليل من مؤشرات الترابط العاملة الإضافية لمضاعفة الحد الأقصى للاتصالات في الوكيل الذي تم تكوينه.
كما توجد إستراتيجية أخرى نستخدمها عند وضع عمليات التحقق من السلامة في الأولوية وهي أن تقوم الخوادم بتنفيذ فرض الحد الأقصى للطلبات المتزامنة. وفي هذه الحالة، يُسمح دومًا بإجراء عمليات التحقق من سلامة موازن الأحمال، ولكن يتم رفض الطلبات العادية إذا كان الخادم يعمل بالفعل وفقًا لبعض الحدود. تمتد عمليات التنفيذ في شركة Amazon من إشارة بسيطة في Java إلى تحليل أكثر تعقيدًا للاتجاهات في استخدام وحدة المعالجة المركزية.
وتتمثل الطريقة الأخرى، المُستخدمة لضمان استجابة الخدمات في الوقت المناسب لطلب اختبار الاتصال في التحقق من السلامة، في إجراء منطق التحقق من سلامة التبعية في مؤشر ترابط الخلفية وتحديث علامة isHealthy الذي يتحقق منها منطق اختبار الاتصال. وفي هذه الحالة، تستجيب الخوادم سريعًا لعمليات التحقق من السلامة وينتج عن التحقق من سلامة التبعية أحمال متوقعة في النظام الخارجي التي تتعامل معه. وعندما تجري فِرق العمل هذه العملية، فإنها تتوخى الحذر الشديد بشأن اكتشاف حالة فشل في مؤشر ترابط التحقق من السلامة. في حالة وجود مؤشر ترابط الخلفية، لا يكتشف الخادم حالة فشل في الخادم في المستقبل (أو عملية استرداد!).
الموازنة بين عمليات التحقق من سلامة التبعية ونطاق التأثير
تتسم عمليات التحقق من سلامة التبعية بأنها جذابة نظرًا لأنها تعمل باعتبارها اختبارًا شاملاً يتم إجراؤه على سلامة الخادم. وللأسف، يمكن أن تتسم بالخطورة نظرًا لأن إحدى التبعيات يمكن أن تؤدي إلى حدوث فشل متتالٍ في النظام.
يمكننا تكوين وجهات نظر بشأن التعامل مع تبعيات التحقق من السلامة من خلال إلقاء نظرة على الهندسة الموجّهة للخدمة في شركة Amazon. وتكون كل الخدمات في شركة Amazon مُصممة خصيصًا لإجراء بعض الأمور بحيث لا توجد وحدة تقوم بإجراء كل الأمور. توجد العديد من الأسباب التي تكمن وراء رغبتنا في إنشاء خدمات بهذه الطريقة، بما في ذلك سرعة وتيرة الابتكار التي تتسم بها فِرق العمل الصغيرة ونطاق التأثير المنخفض في حالة وجود مشكلة في إحدى الخدمات. ويمكن أن ينطبق هذا التصميم الهندسي على عمليات التحقق من السلامة أيضًا.
عندما تستدعي إحدى الخدمات خدمة أخرى، فإنها تعتمد على هذه الخدمة. وإذا لم تقم الخدمة أحيانًا إلا باستدعاء التبعية، فقد نراعي أن تكون التبعية "تبعية بسيطة" نظرًا لأنه يمكن للخدمة إجراء بعض أنواع الأعمال حتى إذا لم تتمكّن من التعامل مع التبعية. ودون استخدام الحماية من فشل الفتح، يؤدي تنفيذ التحقق من السلامة الذي يختبر التبعية إلى تحويل هذه التبعية إلى "تبعية صعبة". في حالة حدوث عطل في التبعية، يحدث عطل في الخدمة أيضًا مما يؤدي إلى حدوث فشل متتالٍ مع تأثير النطاق المتزايد.
ومع ذلك، نقسّم الوظائف إلى خدمات مختلفة بحيث تستخدم كل خدمة العديد من واجهات برمجة التطبيقات. وأحيانًا تتضمن واجهات برمجة التطبيقات الموجودة بالخدمة التبعيات الخاصة بها. وإذا تأثرت إحدى واجهات برمجة التطبيقات، فإننا نفضل أن تواصل الخدمة عملها في واجهات برمجة التطبيقات الأخرى. فعلى سبيل المثال، يمكن أن تكون الخدمة إحدى مستويات التحكم (مثل واجهات برمجة التطبيقات التي تُعرف أحيانًا بواجهات CRUD في الموارد طويلة المدى) وإحدى مستويات البيانات (واجهات برمجة التطبيقات عالية الإنتاجية والمهمة جدًا للأعمال). نريد أن تواصل واجهات برمجة التطبيقات الخاصة بمستوى البيانات عملها حتى إذا كانت واجهات برمجة التطبيقات الخاصة بمستوى التحكم تواجه مشكلات في التعامل مع التبعيات.
وكذلك، حتى أنه قد تتصرف واجهة واحدة من واجهات برمجة التطبيقات بطريقة مختلفة بناءً على إدخال البيانات أو حالتها. علمًا بأن النمط الشائع هو واجهة برمجة تطبيقات القراءة التي تستعلم عن قاعدة البيانات، ولكنها تخزّن الاستجابات محليًا لبعض الوقت. في حالة تعطل قاعدة البيانات، يمكن أن تظل الخدمة تستخدم حالات القراءة المخزّنة مؤقتًا إلى أن تتم إعادة الاتصال بقاعدة البيانات عبر الإنترنت. يؤدي فشل عمليات التحقق من السلامة عندما يكون مسار تعليمة برمجية واحد فقط غير سليم إلى زيادة نطاق تأثير المشكلة التي تعاني منها التبعية.
تثير هذه المناقشة المتعلقة بتحديد التبعية المطلوب التحقق من سلامتها سؤالاً مهمًا بشأن المفاضلات بين الخدمات الصغيرة والخدمات المتجانسة ذات الصلة. نادرًا ما توجد قاعدة واضحة بشأن عدد الوحدات أو نقاط النهاية التي يمكن نشرها لتقسيم الخدمة، ولكن يمثل السؤالان "ما التبعيات المطلوب التحقق من سلامتها" و"هل تزيد حالة الفشل من نطاق التأثير" منظورين مهمين يتعين استخدامها لتحديد الخدمة الصغيرة أو الخدمة الكلية.
أمور واقعية فشلت عند إجراء عمليات التحقق من السلامة
قد يكون كل ذلك منطقيًا من الناحية النظرية، ولكن ماذا يحدث للأنظمة من الناحية العملية عند إجراء عمليات التحقق من السلامة بشكل خاطئ؟ بحثنا عن الأنماط في القصص الواردة من عملاء AWS ومن شركة Amazon في مختلف الأنحاء بغرض توضيح الصورة الأكبر. كما أننا ألقينا نظرة في عوامل التعويض - أشكال "الحذر" التي تتبّعها فِرق العمل حتى لا تتسبب مواطن الضعف في عمليات التحقق من السلامة في حدوث مشكلة واسعة النطاق.
يتضمن أحد أنماط المشكلات الموجودة في التحقق من السلامة عمليات النشر. ترسل أنظمة النشر مثل AWS CodeDeploy تعليمة برمجية جديدة إلى مجموعة فرعية من الأسطول في وقت واحد بحيث تنتظر اكتمال عملية النشر قبل الانتقال إلى الخطوة التالية. وتعتمد هذه العملية على الخوادم التي تعيد إرسال التقارير إلى نظام النشر بمجرد وصولها وتشغليها باستخدام التعليمة البرمجية الجديدة. وإذا لم تُرسَل التقارير مرة أخرى، فسيجد نظام النشر أن هناك خطأ في التعليمة البرمجية الجديدة ويعيد النشر إلى حالته السابقة.
قد يشكّل البرنامج النصي الأساسي لنشر بدء تشغيل الخدمة عملية الخادم ببساطة ويستجيب "النشر الكامل" على الفور لنظام النشر. ومع ذلك، يشكّل ذلك خطرًا نظرًا لأنه قد تفشل العديد من الأمور عند استخدام التعليمة البرمجية الجديدة: قد تتعطل التعليمة البرمجية الجديدة مباشرة بعد بدء التشغيل أو تكون معلقة وتفشل في البدء بمأخذ توصيل الخادم أو تفشل في تحميل التكوين اللازم لمعالجة الطلبات بنجاح أو تواجه خطأ. إذا لم يتم تكوين نظام النشر لاختباره مقابل التحقق من سلامة التبعية، فإنه لا يدرك أنه يرسل عملية نشر سيئة. ولكنه يواصل العمل بحيث يعمل على تعطل خادم تلو الآخر.
ولحسن الحظ، تقوم فِرق العمل في شركة Amazon من الناحية العملية بتنفيذ العديد من أنظمة التخفيف لمنع هذا السيناريو من التخلص من الأسطول بالكامل. تتمثل إحدى عمليات التخفيف هذه في تكوين التنبيهات التي تعمل عندما يكون حجم الأسطول بالكامل صغيرًا جدًا أو عندما يعمل في حمولة عالية أو عندما يوجد زمن انتقال عالٍ أو معدل أخطاء عالٍ. وفي حالة تشغيل هذه التنبيهات، يعمل نظام النشر على إيقاف النشر ويعود إلى حالته السابقة.
بينما يتمثل النوع الآخر من التخفيف في استخدام عمليات النشر المرحلية. وبدلاً من نشر الأسطول بالكامل في عملية نشر واحدة، يمكن تكوين الخدمة لنشر مجموعة فرعية وربما منطقة توفر الخدمات قبل إيقاف المجموعة الكاملة لاختبارات الدمج مؤقتًا وتشغيلها مقابل هذه المنطقة. تكون محاذاة عملية النشر هذه لكل منطقة توفر خدمات ملائمة نظرًا لأن الخدمات مُصممة بالفعل بحيث يمكنها التشغيل في حالة وجود مشكلات في منطقة واحدة من مناطق توفر الخدمات.
وبالطبع قبل النشر في الإنتاج، ترسل فِرق العمل في شركة Amazon هذه التغييرات من خلال بيئات الاختبار وتجري اختبارات الدمج التلقائية التي قد تدرك هذا النوع من الفشل. ومع ذلك، قد توجد اختلافات دقيقة وحتمية بين بيئات الإنتاج والاختبار، لذا فمن المهم تجميع طبقات النشر المتعددة بأمان من أجل إدراك كل أنواع المشكلات قبل التأثير في الإنتاج. بينما تكون عمليات التحقق من السلامة مهمة لحماية الخدمات من عمليات النشر السيئة، فإننا نضمن عدم التوقف عند هذه المرحلة. نحن نراعي استخدام نُهج "الحذر" التي تعمل باعتبارها نقاط دعم تُستخدم لحماية الأساطيل من هذه العمليات ومن الأخطاء الأخرى.
يتعلق نمط آخر من أنماط الفشل بمعالجة الرسائل غير المتزامنة، مثل الخدمة التي تعمل من خلال فحص قائمة انتظار SQS أو تدفق Amazon Kinesis. وعلى عكس ما يحدث في الأنظمة حيث إنها تحصل على الطلبات من موازنات الأحمال السيئة، لا يوجد أي إجراء يمكنه تلقائيًا تنفيذ عمليات التحقق من السلامة لإخراج الخوادم من الخدمة.
وعندما لا تتضمن الخدمات عمليات تحقق من السلامة عميقة بما يكفي، فقد تتضمن الخوادم العاملة في قائمة الانتظار الفردية حالات فشل مثل الأقراص الممتلئة بأدوات وصف الملفات أو الأقراص التي تنفد منها أدوات وصف الملفات. لن تؤدي هذه المشكلة إلى توقف الخادم عن تشغيل قائمة الانتظار، إلا أنها ستؤدي إلى توقف الخادم عن معالجة الرسائل بنجاح. كما أدت هذه المشكلة إلى حدوث تأخر في معالجة الرسائل أثناء تشغيل الخادم السيئ من قائمة الانتظار سريعًا وفشله في التعامل معها.
وفي هذه الحالة، توجد غالبًا عدة عوامل تعويض تساعد على تضمين التأثير. فعلى سبيل المثال، في حالة فشل الخادم في معالجة الرسالة التي تعمل على تشغيل SQS، من ثمّ يعيد SQS إرسال هذه الرسالة إلى خادم آخر بعد انتهاء مهلة عرض الرسالة التي تم تكوينها. يزيد زمن الانتقال الشامل، ولكن لا تنقطع الرسائل. ويتمثل عامل التعويض الآخر في التنبيه الذي يتوقف عن التشغيل عند وجود عدد كبير من الأخطاء قد تجاوز الحد الأقصى في رسائل المعالجة بحيث تعمل على تنبيه المشغّل من أجل إجراء عملية الفحص.
تندرج ضمن حالات الفشل الأخرى التي تواجهها الأقراص التي تكون ممتلئة في الخوادم مما يؤدي إلى فشل المعالجة والتسجيل. ويؤدي هذا الفشل إلى حدوث فجوة في مراقبة الرؤية نظرًا لأن الخادم قد لا يتمكّن من إبلاغ نظام المراقبة عن حالات الفشل.
ومرة أخرى، تمنع العديد من عناصر التحكم في التخفيف من "التعتيم الخفي" وتخفف من التأثير سريعًا. ستتضمن الأنظمة المُقدمة من وكيل مثل Application Load Balancer أو بوابة واجهة برمجة التطبيقات أدوات لقياس معدل الأخطاء وزمن الانتقال التي ينتج عن هذا الوكيل. وفي هذه الحالة، تعمل التنبيهات حتى إذا كان الخادم لا يبلغ عنها. بالنسبة إلى الأنظمة المستندة إلى قائمة الانتظار، تُعد خدمات مثل Amazon Simple Queue Service (Amazon SQS) تقارير لأدوات القياس تفيد بأن المعالجة في بعض الرسائل.
الأمر المشترك بين هذه الحلول هو وجود طبقات متعددة من المراقبة. ويبلغ الخادم بنفسه عن الأخطاء، وكذلك النظام الخارجي. ويمثل المبدأ نفسه أهمية في عمليات التحقق من السلامة. ويمكن للنظام الخارجي اختبار سلامة النظام المتوفر بدقة أكبر مما يمكنه عند اختبار نفسه. ولذلك عند استخدام AWS Auto Scaling، تعمل فِرق العمل على تكوين موازن أحمال لإجراء عمليات التحقق من سلامة اختبار الاتصال الخارجي.
كما تكتب فِرق العمل نظام التحقق من السلامة المخصص بحيث يطلب من كل الخوادم دوريًا تحديد ما إذا كان سليمًا أم لا ويرسل تقارير إلى AWS Auto Scaling عندما يكون الخادم غير سليم. تتضمن إحدى عمليات التنفيذ الشائعة في هذا النظام دالة Lambda التي يتم تشغيلها كل دقيقة مما يؤدي إلى اختبار سلامة كل الخوادم. يمكن لعمليات التحقق من السلامة هذه الاحتفاظ بحالتها بين كل عملية تشغيل في شيء ما مثل DynamoDB بحيث إنها لا تحدد دون قصد عددًا كبيرًا من الخوادم يتجاوز الحد الأقصى باعتبارها خوادم غير سليمة في وقت واحد.
يتضمن نمط آخر من المشكلات الخوادم بين التشغيل وإيقاف التشغيل. ويمكن أن يتم قطع اتصال الخوادم عن الشبكة لفترات زمنية ولكنها تظل قيد التشغيل، أو يمكن إيقاف تشغيلها لفترات زمنية ممتدة وإعادة تشغيلها لاحقًا.
عندما تتم إعادة تشغيل الخوادم بين التشغيل وإيقاف التشغيل، فإنها لا تتزامن بدرجة كبيرة مع بقية الأسطول مما يؤدي إلى حدوث مشكلات جسيمة. فعلى سبيل المثال، في حالة قيام خادم بين التشغيل وإيقاف التشغيل بتشغيل إصدار قديم وغير متوافق من البرامج، يمكن أن يؤدي إلى حدوث حالات فشل عندما يحاول التفاعل مع قاعدة بيانات تتمتع بمخطط مختلف أو يمكن أن يستخدم التكوين الخاطئ.
وللتعامل مع الخوادم بين التشغيل وإيقاف التشغيل، تستجيب غالبًا الأنظمة لعمليات التحقق من السلامة من خلال إصدار البرامج الذي يتم تشغيله حاليًا. وبعد ذلك، يعقد وكيل المراقبة المركزي مقارنة بين الاستجابات التي تتم في الأسطول بغرض البحث عن أي شيء يعمل على تشغيل إصدار قديم بشكل مفاجئ، بالإضافة إلى أنه يمنع هذه الخوادم من الانتقال مرة أخرى إلى الخدمة.
الختام
تتعرّض الخوادم والبرامج التي تعمل عليها للفشل نتيجة لكل هذه الأسباب التي تتسم بالغرابة نوعًا ما. وفي النهاية تتعرّض الأجهزة المادية للتلف. بصفتنا مطورين للبرامج، نكتب في النهاية بعض الأخطاء مثل الخطأ الذي تناولناه في بداية هذا المقال والذي أدى إلى تعطل البرامج. تحتاج العديد من طبقات عمليات التحقق بداية من عمليات التحقق الحية غير المهمة إلى المراقبة غير الفعالة لأدوات القياس لكل خادم إلى إدراك كل أنواع أوضاع حالات الفشل غير المتوقعة.
عند حدوث حالات الفشل هذه، من المهم اكتشافها وإيقاف تشغيل الخوادم المتضررة سريعًا. ومع ذلك، كما هو الحال في عملية أتمتة الأسطول، إننا نضيف تقييدًا على المعدل وحدًا وقواطع دائرة يوقف تشغيل الأتمتة ويجعل الأشخاص يتفاعلون في حالات الشك أو في الحالات القصوى. يُعد فشل الفتح وإنشاء عوامل مركزية بمثابة إستراتيجيتين للاستمتاع بمزايا التحقق من السلامة العميق من خلال أمان الأتمتة المحدودة حسب المعدل.
تدريب عملي
جرّب بعض المبادئ التي تعلمتها هنا من خلال تدريب عملي.
نبذة عن المؤلف
ديفيد ياناسيك هو كبير مهندسين يعمل في AWS Lambda. وعمل ديفيد مطورًا للبرمجيات في Amazon منذ عام 2006، وكان يعمل سابقًا في تطوير Amazon DynamoDB وAWS IoT، وكذلك أطر عمل خدمة الويب الداخلية وأنظمة التشغيل الآلي لعمليات الأسطول. ومن الأنشطة المفضلة لديفيد في العمل هي تحليل السجلات والتحري عن طريق المقاييس التشغيلية لإيجاد طرق لجعل الأنظمة تعمل بسلاسة أكثر بمرور الوقت.