البداية · فصل ١

ليه محتاج أكتر من Process أصلًا؟

single thread · event loop · CPU cores · process
🎯 الهدف: تفهم إن الـ process الواحدة بتشغّل الـ JavaScript على core واحد، وإن fork وcluster إجابتين مختلفتين لسؤال "أستغل باقي الـ cores إزاي؟".

الفكرة الأساسية

Node بيشغّل كود الـ JavaScript بتاعك على thread واحد. يعني لو السيرفر فيه 8 cores، الـ process الواحدة هتشغّل كودك على core واحد بس، والسبعة التانيين قاعدين.

السؤال اللي المذكرة كلها بتجاوب عليه: إزاي أستغل باقي الـ cores؟

وفي PM2، الإجابة دي اسمها exec_mode، وليها قيمتين بس:

fork

كل instance هي process مستقلة تمامًا، ومفيش بينها وبين التانية أي مشاركة.

cluster

workers كتير بيشتغلوا من خلال process رئيسية، وكلهم بيشاركوا نفس الـ port.

القيمتين دول مش اختراع من PM2. الاتنين مبنيين على حاجات موجودة في Node نفسه: child_process.fork() والـ cluster module.

طب إزاي Node بيخدم ألف request وهو thread واحد؟

لأن أغلب شغل السيرفر هو انتظار: query على الداتابيز، أو request لـ API تاني، أو قراية ملف. وأثناء ما Node مستني، بيروح يخدم request تاني. وده اسمه concurrency.

لكن لو الكود نفسه بيحسب حاجة تقيلة، زي loop كبيرة أو تشفير أو معالجة صورة، فالـ thread بيبقى مشغول، وكل الـ requests التانية بتستنى وراه. وهنا بتحتاج processes أكتر، أو worker_threads لو الحساب جوه request واحدة. وده هنرجعله في فصل المقارنة.

السيرفر اللي هنجرّب عليه

server.js
const http = require("node:http");const PORT = process.env.PORT || 3000;http  .createServer((req, res) => res.end(`pid ${process.pid} on port ${PORT}\n`))  .listen(PORT, () => console.log(`pid ${process.pid} listening on ${PORT}`));

كل response فيه الـ pid. فلما تبعت كذا request وتلاقي الرقم بيتغيّر، تعرف إن الطلبات راحت لـ processes مختلفة.

الـ default في PM2

terminal
pm2 start server.js           # fork، process واحدةpm2 start server.js -i 4      # cluster تلقائي، 4 workerspm2 start server.js -i max    # cluster، worker لكل corepm2 start server.js -i 4 -x   # 4 processes بس fork
  • الـ default هو fork.
  • أول ما تكتب -i في الـ CLI على Node app، PM2 بيحوّل لـ cluster لوحده حتى لو مقولتلوش.
  • لو عايز كذا instance في fork، استخدم -x (اسمها --execute-command). مفيش flag اسمه --exec-mode في الـ CLI.
  • أي حاجة مش Node، زي Python أو bash أو binary، بتشتغل fork دايمًا.

خلّصت الفصل لما

🧠 اختبر نفسك
١) سيرفر فيه 8 cores وشغلت node server.js. كام core بتشغّل كودك؟
واحد. Node مش بيقسم كودك على الـ cores لوحده.
٢) pm2 start server.js من غير أي flags، الـ mode إيه؟
fork، وprocess واحدة.
٣) pm2 start server.js -i 4، الـ mode إيه؟
cluster، لأن -i على Node app بتحوّل لـ cluster تلقائيًا.