القرار · فصل ٤

تختار Fork ولا Cluster؟

stateless · Redis · cron · WebSocket · worker_threads
🎯 الهدف: تقارن الوضعين، وتعرف المشاكل اللي بتظهر لما التطبيق يبقى كذا نسخة، وتختار الصح لكل حالة.

المقارنة

ForkCluster
الـ portport لكل processport واحد للكل
مين بيوزّع؟Nginx أو LB برّهPM2 (الـ primary)
اللغةأي حاجةNode بس
pm2 reload بدون downtimeلأ، بيبقى restartأيوه
memory مشتركة؟لأبرضه لأ

السطر الأخير هو أهم سطر: في الوضعين، كل instance ليها memory لوحدها. cluster معناه port مشترك، مش memory مشتركة.

المشاكل اللي بتظهر لما التطبيق يبقى N نسخة

أي حاجة متخزنة في متغير جوه الـ process هتبقى N نسخة مختلفة:

Session أو cache في RAM

المستخدم يعمل login عند worker 1، والـ request الجاي يروح worker 2 فميلاقيش الـ session. الحل إنك تحطها في Redis أو في الداتابيز.

Rate limiter في RAM

كل worker بيعد لوحده. حد 100 request مع 4 workers بيبقى في الحقيقة 400. الحل store مشتركة.

Cron جوه التطبيق

الـ job بتشتغل N مرة، مرة في كل worker. يعني إيميل التقرير يوصل 8 مرات. الحل إنك تشغّل الـ cron في process لوحدها (fork، instance واحدة)، أو تستخدم lock في Redis.

Socket.io

الـ client متوصل بـ worker معين، فرسالة من worker تاني مش هتوصله. محتاج Redis adapter، ومحتاج sticky sessions لو فيه polling.

إمتى تستخدم إيه؟

  • API أو web server بـ Node على VPS: cluster مع instances: "max"، وبشرط إن التطبيق stateless.
  • Worker بيسحب من queue، أو cron، أو سكريبت: fork، instance واحدة.
  • أي حاجة مش Node: fork. مفيش اختيار تاني.
  • Docker أو Kubernetes: غالبًا process واحدة لكل container، وزوّد الـ replicas. الـ orchestrator هو اللي بيوزّع ويرجّع اللي يقع، فـ cluster جوه كل container بيبقى طبقة زيادة.
  • request واحدة بتعمل حساب تقيل: cluster مش هيسرّعها، لأنه بيوزّع requests مختلفة بس. استخدم worker_threads أو job queue.

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

🧠 اختبر نفسك
١) 4 workers وrate limit في RAM قيمته 100. الحد الحقيقي كام؟
لحد 400، لأن كل worker بيعد لوحده.
٢) cron بيبعت إيميل جوه تطبيق شغال بـ instances max على 8 cores. كام إيميل؟
8، مرة من كل worker.
٣) cluster هيسرّع request بتعالج صورة كبيرة؟
لأ. الـ request الواحدة بتفضل على worker واحد. استخدم worker_threads أو queue.