لماذا ظهرت خوادم الويب غير المتزامنة؟

تحية للجميع. على اتصال فلاديسلاف رودين. حاليًا ، أنا رئيس دورة High Load Architect في OTUS ، وأدرس أيضًا دورات في هندسة البرمجيات.

بالإضافة إلى التدريس ، كما ترون ، كنت أكتب لمدونة حقوق النشر OTUS Habré ومقال اليوم الذي أريد أن يتزامن مع بداية دورة «Linux Administrator» ، والتي أصبحت الآن مفتوحة للمجموعة.





المقدمة


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

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

ميزات نظام التشغيل Linux


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

تبديل السياق


على الأرجح ، أي مستخدم يعرف أنه يمكن تنفيذ برنامج واحد فقط على نواة معالج واحدة في وقت واحد سيسأل: "لماذا يمكن إطلاق 20 برنامجًا على معالج 4 نوى في المرة الواحدة؟".

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

تم ذكر مفتاح السياق أعلاه. ماذا تشمل؟ عند تبديل السياق ، من الضروري حفظ سجلات المعالج ، لمسح مسار تعليماته ، لحفظ مناطق الذاكرة المخصصة للعملية. بشكل عام ، العملية مكلفة للغاية. يستغرق ~ 0.5 μs ، في حين أن تنفيذ سطر بسيط من التعليمات البرمجية ~ 1 ns. علاوة على ذلك ، مع زيادة عدد العمليات لكل نواة معالج ، ستزداد النفقات العامة لتبديل السياق.

نماذج خادم الويب


توجد حاليًا نماذج خادم الويب التالية:

  • عامل
  • بريورك
  • غير متزامن
  • مشترك


دعونا نناقش كل واحد على حدة.

عامل وبرورك


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

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

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

عامل مقابل بريورك


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

نموذج غير متزامن


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

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

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

نموذج مدمج


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

استنتاج


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

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



تعلم المزيد عن الدورة.



All Articles