ماهو الـSingle Thread Event Loop في الـNodeJS
السلام عليكم ورحمة الله وبركاته..
قبل الدخول في هذا الموضوع و عرض الأمثلة، اود ان اوجه كلمة، من السهولة تعلم أي لغة برمجية تريد ولكن لن تستطيع برمجة تطبيق جيد الا من خلال فهم كيفية عمل هذه اللغة/فريمورك او الـEnvironment لذا، من المهم جدا أن تعرف كيفية عمل كل لغة تحت الغطاء، ماذا يدور في الخفاء وكيف تشتغل.
في هذا الدرس سنتحدث عن اركتجر الـNodeJS ومفهوم Single Threaded Event Loop
الكثير من تكنولوجيات التطبيقات تعمل على Multi-Thread Model مثل JSP, Spring MVC, ASP.NET ، ولكن مع الـNodeJS الامر مختلف فتطبيق النود هو عبارة عن تطبيق ++C يتم تحويله إلى لغة الآلة عن طريق محرك للجافاسكربت يدعى V8 حيث تعمل "بيئة" التطبيق على Single Thread
سأفترض ان مبرمجين الـ Functional Languages على علم مسبق بمودل Multithreaded ولكن ما هو الفرق بينه وبين مودل الـNodeJS Single Thread Event Loop ؟
ملاحظة: سنقوم باختصار Single Thread Event Loop بـSTEL
بلاتفورم الـNodeJS
كما اسلفنا النود يستخدم STEL Architecture بدلا من MultiThreaded اذا كيف يتم تلبية طلبات Requests المستخدمين المختلفة بدون استخدام أكثر من Thread ، وماهو الـEvent Loop Model ؟
اولا: MultiThreaded Model
كل تطبيق ويب غير مبرمج بالنود usually يستخدم هذا المودل، العميل يرسل طلب Request بعد ذلك السيرفر يقوم بعمليات معينة بناءا على طلب العميل، يجهز الجواب Response ويرسله إلى العميل.
هذه المودل يستخدم بروتوكول الـHTTP و بما أن هذا البروتوكول Stateless إذا كذلك Request Response Model يعد Stateless Model
على كل حال "الزبدة" ان هذا المودل يستخدم اكثر من Thread لتلبية طلبات العملاء، و لفهم الامر اكثر، اِطلع على الدايقرام
- الويب سيرفر في حالة infinite loop ينتظر الطلبات القادمة.
-
العميل يرسل طلب للسيرفر.
- الويب سيرفر داخليا يحدد العدد المتوفر من الـThreads لتلبية طلب العميل.
- الطلبات تصل الى الويب سيرفر.
- يستقبل الطلب ، و يعينه الى احد الـThreads المتاحة من بركة الـThreads.
- الثرد يواصل عملية تلبية طلب العميل، يحدد ما اذا كان هناك عمليات IO ام لا بناءا على طلب العميل، يتم التلبية وإعداد الجواب Response.
- يُرسل الجواب العميل.
-
يُفرغ الـThread ويتحول من busy الى await.
السيرفر يدخل في عملية infinite loop ويكرر العملية المذكورة أعلاه لكل طلب ولكل عميل، هذا يعني أن في كل طلب بإستخدام هذا المودل ينشأ Thread واذا كان هنالك عمليات IO Blocking ( عمليات التواصل مع قواعد البيانات مثلا) وعدد طلبات اكثر من الـThreads (وهذا صحيح اغلب الاحيان) اذا مبدئيا كل الـThreads سيكونون في حالة تأهيل الجواب، العملاء الآخرين في حالة انتظار داخل صف queue لحين وجود Thread متاح، مع التنبيه انه وقبل تعيين الثرد الى عميل اخر والتحول من حالة busy الى await يجب ان يتم تفريغه لأنه يأخذ حيز من resources السيرفر مثل الرام واذا اردت ان يكون تطبيقك جيد يجب عليه ترقية السيزفر الذي يشتغل عليه التطبيق بشكل مستمر و بمبالغ باهضة
اقتباسنفهم من ذلك أن تلبية طلبات العملاء بعدد كبير سيكون صعب و مكلف حيث ستحتاج الى عتاد قوي مع الايام و يكبر كل حين ناهيك عن الوقت الضائع من قبل العملاء في اي طلب من عميل اخر.
ثانيا: اركتجر Architecture الـ NodeJS و مفهوم الـSTEL
بلاتفورم النود لا يتبع المودل أعلاه بل يعمل على مفهوم آخر أساسه Single Thread مستوحى من تقنية الـcallback في الجافاسكربت، يجب ان يكون لديك فكرة ولو بسيطة عن تقنية او mechanism الـcallback لفهم ما سيتم شرحه الآن.
اساس عمليه تلبية طلبات العملاء في النود هو Event Loop و بما ان Architecture النود يتبع هذه المكانيسم، اذا يستطيع تلبية طلبات العملاء الكثيرة بشكل بسيط وسريع
- العميل يرسل طلب الى الويب سيرفر
- ويب سيرفر النود داخليا يحدد عدد الـThreads المتوفره في السيرفر.
- ويب سيرفر النود يستقبل الطلب ويدخله في صف Queue يسمى بالـEvent Queue.
- يوجد مكون في النود يدعى Event loop يسمى بذلك لانه يستخدم indefinite loop ليستقبل الطلبات ويعمل على تلبيتها.
- indefinite loop هو بكل بساطه عن لوب ينتظر أمر ما ليحقق true وكذلك غير معلوم تكراره، في حالتنا الكوندشن هو الطلب Request.
- الـEvent Loop يستخدم Thread واحد فقط وهو الـMain Thread، مهمته ان يفحص ما اذا كان هناك طلب من العميل ام لا، اذا وجد الطلب ادخله في الـEvent Queue واذا لم يوجد، بقي في حالة الـindefinitely.
- إذا وجد طلب في Event Queue ، يبدأ بعملية التلبية.
- إذا كان الطلب لا يوجد به عمليات IO، يتم إعداد الجواب Response وإرساله للعميل.
- إذا كان طلب العميل يوجد به عمليات IO مثل التواصل مع قواعد البيانات، يعين هذا الجزء من الطلب إلى أحد الـThreads المتوفرة التي هي أساسا في C++ Thread Pool مكونة بإستخدام مكتبة libuv، حيث يعمل الـThread على عملية التواصل مع قاعدة البيانات.
- يجهز Response ويرسله مره اخرى الى الـMain Thread الذي يتواجد فيه الـEvent loop و الذي بدوره يرسله الى العميل.
لوهلة قد تعتقد ان وجود التواصل بين الـEvent loop و الـThread هي عملية زائدة قد تطيل من بروسس تلبية طلب العميل، بينما في الحقيقة هذا الـThread غير تابع للنظام إنما كما وضحت تابع الى Thread Pool مبرمجة بالـ++C بإستخدام مكتبة Libuv، بالتالي لن يكون هناك حاجة لإنشاء Thread حقيقي لكل عميل حيث تعد هذه العملية مكلفة وتذكر دائما مقولة ان "الرام مكلفة".
العدد الافتراضي للـC++ Threads هو 4 او 5، تستطيع زيادة هذا العدد من خلال كتابة هذا السطر في الكود (x) هو العدد المطلوب
process.env.UV_THREADPOOL_SIZE = x؛
وإذا اردت كذلك استخدام الطريقة الاعتيادية الى الـMulti Threading تستطيع ذلك من خلال استخدام مكتبة Cluster (موجودة مسبقا مع تثبيت النود)
اتمنى ان وضحت الفكرة وكيفية عمل النود، جميع الاسئلة مرحب بها هنا او على التويتر AbdullaScript
التعليقات (0)
لايوجد لديك حساب في عالم البرمجة؟
تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !