Node.js / المتقدم: خدمات Node.js موثوقة / الدرس 14
تأخر حلقة الأحداث وتحليل الأداء
ميّز الانتظار عن ضغط المعالج واجمع الأدلة قبل تغيير بنية نظام يعمل.
في هذه الصفحة
أهداف الدرس
- اشرح المفاهيم والمفاضلات المتعلقة بموضوع «تأخر حلقة الأحداث وتحليل الأداء».
- توقع المثالين وتحقق من مخرجاتهما وسلوك تنظيف الموارد فيهما.
- شخّص الإخفاقات الثلاثة الشائعة وطبق الحلول المشروحة على مدخلات مشابهة.
البدء بعرض قابل للملاحظة
لا يحدد الطلب البطيء سببه؛ فقد يستهلك الزمن انتظار اتصال أو رد خارجي أو تنفيذ JavaScript أو جمع الذاكرة أو طابورا. سجل المراحل منفصلة وقارن الطبيعي بالحادث. يختلف التحقيق مع ارتفاع المعالج وتأخر الحلقة عنه مع انخفاض المعالج وتشبع مجمع القاعدة. لا تعد استخدام المضيف كله دليلا على عملية Node معينة. حدد الحمل والإصدار وحدود النشر والفترة قبل الاستنتاج.
قياس التأخر دون توقيت مضمون
تأخذ monitorEventLoopDelay عينات لتأخر العمل المجدول في الحلقة. تستخدم قيمها النانوثانية؛ فحوّلها عمدا عند عرض الملي ثانية. يفعل المثال الأول نافذة قصيرة ويتحقق من وجود عينات بدلا من نشر زمن عام مختلق. تغير الدقة الكلفة وما يمكن رصده. لا تثبت عينة خمول قصيرة زمن الذيل الإنتاجي، والأداة ليست اختبار حمل. أدر تصدير بيانات الفترات وإعادة ضبطها بوعي وافصل آثار الإغلاق عن النوافذ العادية.
قراءة الاستخدام كنسبة
تعرض eventLoopUtilization زمن نشاط الحلقة وخمولها ونسبة الاستخدام. لا تطابق استخدام المعالج في النظام؛ فقد يبقي حجب متزامن الحلقة نشطة مع سلوك مختلف للمعالج. يلتقط المثال الثاني خط أساس ويحسب الفرق بعد انتظار مؤقت. يتحقق من النوع والمدى فقط لأن النسبة تعتمد على الجدولة والحمل. قارن نوافذ متسقة واربط النسب بالتأخر ومعدل الطلبات وقياسات المضيف قبل القول إن العملية تحتاج أنوية أكثر.
import { monitorEventLoopDelay } from 'node:perf_hooks';
import { setTimeout as delay } from 'node:timers/promises';
const histogram = monitorEventLoopDelay({ resolution: 10 });
histogram.enable();
try {
await delay(100);
console.log(histogram.count > 0);
console.log(Number.isFinite(histogram.mean / 1e6));
} finally { histogram.disable(); }
true
true
تُجمع العينات في نافذة خمول محلية. يحوّل القسمة على مليون النانوثانية، ولا يُفترض زمن ثابت.
التقاط تحليل مركز
يأخذ تحليل المعالج عينات للمكدسات ويحدد الدوال المستهلكة خلال نافذة ممثلة. استخدم inspector الرسمية أو خيارات التحليل في بيئة متحكم بها واحم الملفات ولا تكشف مستمع الفحص للعامة. تجيب لقطات الكومة عن سؤال آخر: ما الكائنات المحتفظ بها؟ وقد توقف العملية وتحتاج ذاكرة كبيرة؛ فاختر البيئة والهامش بعناية. ابدأ بفرضية ضيقة وملف واحد؛ فقد تزيد آثار كثيرة غير مترابطة الخطر دون توضيح السبب.
import { performance } from 'node:perf_hooks';
import { setTimeout as delay } from 'node:timers/promises';
const start = performance.eventLoopUtilization();
await delay(20);
const delta = performance.eventLoopUtilization(start);
console.log(typeof delta.utilization);
console.log(delta.utilization >= 0 && delta.utilization <= 1);
number
true
يصف الفرق فترة الملاحظة هذه، ولا تُعرض قيمته العددية معيارا متوقعا صالحا لكل بيئة.
تحويل الدليل إلى تغيير متحقق منه
إذا أشار التحليل إلى تسلسل JSON متكرر فقلل العمل أو خزّن تمثيلا مناسبا قبل إضافة الخيوط. وإذا قادت التخصيصات جمع الذاكرة فافحص الاحتفاظ وأعمار الكائنات بدلا من افتراض تسرب. يعني التسرب احتفاظا غير مطلوب مع الزمن، ويحتاج مقارنة تحت حمل مماثل. أعد الحمل نفسه بعد تغيير واحد وقارن الصحة والمعدل والذيل والذاكرة، مع إمكان الرجوع. يقلل التحليل الشك، ولا تقوى دعوى التحسين أكثر من التجربة الداعمة.
الأخطاء الشائعة وإصلاحها
تبدو قيمة التأخر أكبر بمليون مرة
- لماذا يحدث؟
- وُسمت النانوثواني بالملي ثانية.
- كيف تصلحه؟
- اقسم على1e6 واذكر الوحدة.
- كيف تتجنب تكراره؟
- ضع الوحدات في أسماء القياسات واللوحات.
يُعد انخفاض المعالج دليلا على السلامة
- لماذا يحدث؟
- تنتظر الطلبات طابورا أو اعتمادية خارجية.
- كيف تصلحه؟
- قس انتظار المجمع والزمن الخارجي منفصلين.
- كيف تتجنب تكراره؟
- اربط قياسات الموارد بالطلبات.
يسبب الالتقاط التشخيصي انقطاعا
- لماذا يحدث؟
- التُقط ملف كثيف الذاكرة دون هامش.
- كيف تصلحه؟
- استخدم نسخة معزولة أو إعادة إنتاج متحكما بها.
- كيف تتجنب تكراره؟
- خطط لكلفة الالتقاط واحم ملفاته.
اختبر فهمك
1. تساوي رتبة في المدرج 25000000 نانوثانية. حوّلها واشرح حدها.
اعرض الحل المشروح
اقسم على1000000 فتحصل على25 ملي ثانية. تصف تأخر الحلقة المأخوذ بالعينات في تلك النافذة، لا زمن HTTP الكلي ولا كل حمل مستقبلي. قارن نوافذ متكافئة واربط بزمن الطلب قبل تعيين السبب.
2. تتباطأ الطلبات والمعالج منخفض وانتظار المجمع يزداد. ماذا تحقق أولا؟
اعرض الحل المشروح
افحص استخدام الاتصالات وتسربها وزمن الاستعلام وقدرة الاعتمادية. لا تصلح خيوط JavaScript الإضافية مجمع قاعدة مشبعا. تحقق بالقياسات وإعادة إنتاج متحكم بها قبل تغيير التزامن أو حدود القاعدة.
أهم ما تعلمته
- لا يحدد الطلب البطيء سببه.
- تأخذ monitorEventLoopDelay عينات لتأخر العمل المجدول في الحلقة.
- إذا أشار التحليل إلى تسلسل JSON متكرر فقلل العمل أو خزّن تمثيلا مناسبا قبل إضافة الخيوط.