"لا تحجب حلقة الحدث..." - ربما سمعت هذه الجملة عدة مرات... لست مندهشًا لأنها واحدة من أهم الافتراضات عند العمل مع العقدة. ولكن هناك أيضًا "الشيء" الثاني الذي يجب عليك الامتناع عن حظره - تجمع العمال. إذا تم إهماله، يمكن أن يكون له تأثير كبير على أداء التطبيق وحتى على أمنه.
الخيوط
الشيء الرئيسي الذي يجب تذكره: هناك نوعان من الخيوط في Node.js: الخيط الرئيسي - والذي يتم التعامل معه بواسطة حلقة الحدثو مجمع العمال (تجمع مؤشرات الترابط) - وهو تجمع مؤشرات الترابط -
الشكر لـ libuv. كل واحد منهم لديه وظيفة مختلفة. الهدف من الأولى هو التعامل مع عمليات الإدخال/الإخراج غير المحظورة، والثانية مسؤولة عن العمل المكثف لوحدة المعالجة المركزية وكذلك حظر الإدخال/الإخراج.
ولكن ما هو الخيط وكيف يختلف عن العملية؟ هناك العديد من الاختلافات، ولكن أهمها بالنسبة لنا هو كيفية تخصيص الذاكرة لها. يمكنك أن تفكر في العملية كما لو كانت تطبيقًا. داخل كل معالجة، هناك جزء من الذاكرة مخصص فقط لهذه العملية. لذا، لا يمكن لإحدى العمليات الوصول إلى ذاكرة العملية الثانية، وهذه الخاصية تضمن أمانًا عاليًا. لإنشاء اتصال بينهما، يجب أن نقوم ببعض الأعمال. الخيوط مختلفة. تعمل الخيوط داخل عملية وتتشارك نفس الذاكرة لذا لا توجد مشكلة على الإطلاق في مشاركة الخيوط للبيانات.
ومع ذلك، هناك مشكلة واحدة تسبب مشكلة. تسمى حالة السباق. يمكن أن تعمل الخيوط في نفس الوقت، فكيف نعرف أيهما ينتهي أولًا؟ قد يحدث أنه في المرة الأولى التي تقوم بتشغيلها تنتهي العملية الأولى أولًا، وفي المرة التالية قد يحدث العكس وتنتهي العملية الثانية قبل الأولى. تخيل العمل مع عمليات الكتابة/القراءة في مثل هذه الظروف! كابوس! من الصعب جدًا أحيانًا كتابة العمليات الصحيحة الكود في بيئة متعددة الخيوط.
كما أن اللغات متعددة الخيوط لها نفقات ذاكرة كبيرة لأنها تنشئ مؤشر ترابط منفصل لكل طلب؛ لذا، إذا أردت استدعاء 1000 طلب، فإنها تنشئ 1000 مؤشر ترابط.
كيف تتعامل مع مثل هذه المشكلة؟ استخدم خيطاً واحداً بدلاً من ذلك! وهذا هو ما العقدة تقدم لك
بصفتك JavaScript المطور أشجعك على مشاهدة فيلم
يشرح فيه بارت بيلدر بوضوح مفهوم حلقة الحدث. الرسم البياني أعلاه مأخوذ من عرضه التقديمي. وإذا كنت لا تعرف هذه المصطلحات على الإطلاق، فإن كلاً من العقدة وLibuv وثائق ممتازة 🙂
حول الحجب
في JavaScript تطوير JavaScript الصناعة يقولون ذلك لأن العقدة أحادية الخيوط وغير متوقفة، يمكنك تحقيق تزامن أعلى بنفس الموارد مقارنةً بالحلول متعددة الخيوط. هذا صحيح ولكنه ليس جميلاً وسهلاً كما قد يبدو.
منذ Node.js أحادية الخيط (جزء JS)، فإن المهام كثيفة وحدة المعالجة المركزية ستحظر جميع الطلبات قيد التنفيذ حتى تكتمل المهمة المحددة. لذا، صحيح أنه في Node.js يمكنك حظر كل طلب لمجرد أن أحدها يحتوي على تعليمات حظر بداخله. كود الحجب يعني أن الأمر يستغرق أكثر من بضعة أجزاء من الثانية للانتهاء. لكن لا تخلط بين وقت الاستجابة الطويل والحظر. يمكن أن تستغرق الاستجابة من قاعدة البيانات وقتًا طويلًا جدًا، لكنها لا تحجب عمليتك (التطبيق).
تنفذ الطرق المحظورة بشكل متزامن وتنفذ الطرق غير المحظورة بشكل غير متزامن.
كيف يمكنك إبطاء (أو حظر) حلقة الحدث الخاص بك؟
- التعبير العادي الضعيف - التعبير العادي الضعيف هو التعبير الذي قد يستغرق محرك التعبير العادي الخاص بك وقتًا طويلاً؛ يمكنك قراءة المزيد عنها هنا,
- عمليات JSON على كائنات كبيرة,
- باستخدام واجهات برمجة التطبيقات المتزامنة من العقدة الوحدات الأساسية بدلًا من الإصدارات غير المتزامنة؛ جميع طرق الإدخال/الإخراج في مكتبة Node.js القياسية توفر أيضًا إصداراتها غير المتزامنة,
- أخطاء البرمجة الأخرى، مثل الحلقات اللانهائية المتزامنة.
في هذه الحالة، نظرًا لأن تجمع العمال يستخدم مجموعة من الخيوط، فهل من الممكن حظرها أيضًا؟ للأسف، نعم 🙁 للأسف العقدة تقوم على فلسفة خيط واحد للعديد من العملاء.
لنفترض أن مهمة معينة يقوم بتنفيذها عامل معين معقدة للغاية وتحتاج إلى مزيد من الوقت للانتهاء منها. نتيجة لذلك، يتم حظر العامل ولا يمكن استخدامه لتنفيذ أي من المهام الأخرى المعلقة حتى يتم تنفيذ تعليماته. كما خمنت على الأرجح الآن، قد يؤثر ذلك على الأداء. يمكنك منع مثل هذه المشاكل عن طريق تقليل التباين في أوقات المهام باستخدام تقسيم المهام.
الخاتمة
تجنب الحجب، هذا أمر مؤكد. إذا كنت تستطيع فقط، اختر دائمًا الإصدارات غير المتزامنة من واجهات برمجة التطبيقات للمكتبة القياسية. خلاف ذلك، بعد تشغيل تطبيقك، يمكن أن يواجه العميل بعد تشغيل تطبيقك العديد من المشاكل، بدءًا من انخفاض الإنتاجية وانتهاءً بالانسحاب الكامل، وهو أمر قاتل من وجهة نظر المستخدم.
اقرأ المزيد:
لماذا يجب عليك (على الأرجح) استخدام Typescript
كيف لا تقتل مشروعاً بممارسات الترميز السيئة؟
استراتيجيات جلب البيانات في NextJS