Skip to content

مخططات اللهب

ما هي فائدة مخطط اللهب؟

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

كيفية إنشاء مخطط لهب

ربما سمعت أن إنشاء مخطط لهب لـ Node.js أمر صعب، ولكن هذا غير صحيح (بعد الآن). لم تعد هناك حاجة إلى أجهزة Solaris الظاهرية لمخططات اللهب!

يتم إنشاء مخططات اللهب من مخرجات perf، وهي ليست أداة خاصة بـ Node. ومع ذلك، فهي الطريقة الأقوى لتصور وقت وحدة المعالجة المركزية (CPU) الذي يتم قضاؤه، وقد تواجه مشكلات في كيفية تحسين كود JavaScript في Node.js 8 والإصدارات الأحدث. راجع قسم مشكلات مخرجات perf أدناه.

استخدم أداة مُجمَّعة مسبقًا

إذا كنت تريد خطوة واحدة تنتج مخطط لهب محليًا، فجرّب 0x

لتشخيص عمليات النشر في الإنتاج، اقرأ هذه الملاحظات: 0x خوادم الإنتاج.

إنشاء مخطط لهب باستخدام أدوات perf النظام

الغرض من هذا الدليل هو عرض الخطوات المتضمنة في إنشاء مخطط لهب وإبقائك متحكمًا في كل خطوة.

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

الآن هيا بنا نبدأ العمل.

  1. قم بتثبيت perf (عادةً ما يكون متاحًا من خلال حزمة linux-tools-common إذا لم يكن مثبتًا بالفعل)
  2. حاول تشغيل perf - قد يشتكي من وجود وحدات kernel مفقودة، قم بتثبيتها أيضًا
  3. قم بتشغيل node مع تمكين perf (راجع مشكلات مخرجات perf للحصول على نصائح خاصة بإصدارات Node.js)
bash
perf record -e cycles:u -g -- node --perf-basic-prof app.js
  1. تجاهل التحذيرات ما لم تكن تقول أنك لا تستطيع تشغيل perf بسبب الحزم المفقودة؛ قد تحصل على بعض التحذيرات بشأن عدم القدرة على الوصول إلى عينات وحدة kernel التي لا تبحث عنها على أي حال.
  2. قم بتشغيل perf script > perfs.out لإنشاء ملف البيانات الذي ستصوره في لحظة. من المفيد تطبيق بعض التنظيف للحصول على رسم بياني أكثر قابلية للقراءة
  3. قم بتثبيت stackvis إذا لم يكن مثبتًا بعد npm i -g stackvis
  4. قم بتشغيل stackvis perf < perfs.out > flamegraph.htm

الآن افتح ملف مخطط اللهب في متصفحك المفضل وشاهده يحترق. إنه مرمّز بالألوان بحيث يمكنك التركيز على الأشرطة البرتقالية الأكثر تشبعًا أولاً. من المحتمل أن تمثل دوالًا ثقيلة بوحدة المعالجة المركزية (CPU).

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

استخدام perf لأخذ عينات من عملية قيد التشغيل

هذا رائع لتسجيل بيانات الرسم البياني الناري من عملية قيد التشغيل بالفعل ولا تريد مقاطعتها. تخيل عملية إنتاج بها مشكلة يصعب إعادة إنتاجها.

bash
perf record -F99 -p `pgrep -n node` -- sleep 3

ما فائدة sleep 3؟ إنها موجودة للحفاظ على تشغيل perf - على الرغم من أن الخيار -p يشير إلى معرف عملية مختلف، إلا أنه يجب تنفيذ الأمر على عملية وينتهي به. يعمل perf طوال مدة الأمر الذي تمرره إليه، سواء كنت تقوم بالفعل بتوصيف هذا الأمر أم لا. يضمن sleep 3 أن يعمل perf لمدة 3 ثوانٍ.

لماذا تم تعيين -F (تردد التوصيف) على 99؟ إنه إعداد افتراضي معقول. يمكنك تعديله إذا كنت تريد ذلك. -F99 يخبر perf بأخذ 99 عينة في الثانية، لزيادة الدقة قم بزيادة القيمة. يجب أن تنتج القيم المنخفضة مخرجات أقل بنتائج أقل دقة. تعتمد الدقة التي تحتاجها على المدة التي تعمل فيها وظائفك المكثفة لوحدة المعالجة المركزية بالفعل. إذا كنت تبحث عن سبب لتباطؤ ملحوظ، فيجب أن تكون 99 إطارًا في الثانية أكثر من كافية.

بعد الحصول على سجل perf لمدة 3 ثوانٍ، تابع إنشاء الرسم البياني الناري بالخطوتين الأخيرتين من الأعلى.

تصفية وظائف Node.js الداخلية

عادةً، تريد فقط إلقاء نظرة على أداء مكالماتك، لذلك يمكن أن تجعل تصفية وظائف Node.js و V8 الداخلية الرسم البياني أسهل بكثير في القراءة. يمكنك تنظيف ملف perf الخاص بك باستخدام:

bash
sed -i -r \
    -e '/(_libc_start|LazyCompile) |v8::internal::BuiltIn|Stub|LoadIC:\\[\\[' \
    -e '/^$/d' \
    perf.data > perf.out

إذا قرأت الرسم البياني الناري الخاص بك وبدا غريبًا، كما لو كان هناك شيء مفقود في الوظيفة الرئيسية التي تستغرق معظم الوقت، فحاول إنشاء الرسم البياني الناري الخاص بك بدون عوامل التصفية - ربما تكون قد حصلت على حالة نادرة لمشكلة في Node.js نفسه.

خيارات التوصيف الخاصة بـ Node.js

--perf-basic-prof-only-functions و --perf-basic-prof هما الخياران المفيدان لتصحيح أخطاء كود JavaScript الخاص بك. تُستخدم الخيارات الأخرى لتوصيف Node.js نفسه، وهو خارج نطاق هذا الدليل.

تنتج --perf-basic-prof-only-functions مخرجات أقل، لذلك فهو الخيار الذي لديه أقل حمل.

لماذا أحتاج إليها على الإطلاق؟

حسنًا، بدون هذه الخيارات، ستحصل على رسم بياني لهب، ولكن مع معظم الأشرطة التي تحمل اسم v8::Function::Call.

مشكلات إخراج Perf

تغييرات مسار V8 في Node.js 8.x

تأتي Node.js 8.x والإصدارات الأحدث مع تحسينات جديدة لمسار تجميع JavaScript في محرك V8 مما يجعل أسماء/مراجع الدوال غير قابلة للوصول إلى perf في بعض الأحيان. (يُطلق عليه Turbofan)

والنتيجة هي أنك قد لا تحصل على أسماء الدوال الخاصة بك بشكل صحيح في الرسم البياني للهب.

ستلاحظ ByteCodeHandler: حيث تتوقع أسماء الدوال.

يحتوي 0x على بعض التخفيفات المضمنة لذلك.

للحصول على التفاصيل، راجع:

Node.js 10+

تعالج Node.js 10.x المشكلة المتعلقة بـ Turbofan باستخدام العلامة --interpreted-frames-native-stack.

قم بتشغيل node --interpreted-frames-native-stack --perf-basic-prof-only-functions للحصول على أسماء الدوال في الرسم البياني للهب بغض النظر عن مسار V8 الذي استخدمه لتجميع JavaScript الخاص بك.

تسميات تالفة في الرسم البياني للهب

إذا كنت ترى تسميات تبدو هكذا

bash
node`_ZN2v88internal11interpreter17BytecodeGenerator15VisitStatementsEPMS0_8Zone

فهذا يعني أن Linux perf الذي تستخدمه لم يتم تجميعه مع دعم demangle، راجع https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654 على سبيل المثال

أمثلة

تدرب على التقاط الرسوم البيانية للهب بنفسك من خلال تمرين الرسم البياني للهب!