تطبيقات Node.js
Node.js، نبنيه ونشغّله بجانب PHP لديك.
نبني بـ Node واجهات برمجية، ومواقع تُعرض من الخادم، وخدمات فورية، وعمّالًا في الخلفية، ونشغّلها على الخوادم نفسها التي تعمل عليها مواقع PHP لديك، خلف Nginx واحد.
Node.js
Express
npm
NGINX
MySQL
PostgreSQL
Redis
ما نبنيه بـ Node
خمسة أنواع من العمل، وكل منها هنا لأن Node يناسبه.
-
01
Express
واجهات برمجية وخوادم خلفية صغيرة ومباشرة: مسارات قليلة، وطبقات وسيطة واضحة، ولا شيء مخفي.
واجهات برمجية وخوادم خلفية -
02
NestJS
خدمات أكبر مبنية على وحدات وحقن التبعيات وعقود محددة الأنواع بلغة TypeScript، لشيفرة سينمّيها فريق على مدى سنوات.
خدمات منظّمة -
03
Next.js · Nuxt
عرض من جهة الخادم لـ React وVue: تصل الصفحات جاهزة لمحركات البحث ولظهور أول سريع، ثم تعمل كتطبيق.
مواقع تُعرض من الخادم -
04
Socket.IO · WebSockets
محادثات وإشعارات ولوحات متابعة حية وتتبّع، تتحدّث لحظة حدوث أي تغيير عبر اتصال واحد مفتوح.
الوقت الفعلي -
05
العمّال والطوابير
مهام في الخلفية ومهام مجدولة ومستهلكو طوابير على Redis، تُبقي العمل البطيء خارج الطلب.
العمل في الخلفية
لماذا يُجيد Node الانتظار
تشغّل عملية Node شيفرة JavaScript على خيط واحد، وتترك الانتظار - للقرص والشبكة وقاعدة البيانات - للنظام. وبهذا تُبقي عملية واحدة اتصالات كثيرة مفتوحة في آن واحد.
- تعمل شيفرتك على مكدّس الاستدعاءات، دالة واحدة في كل مرة.
- يغادر العمل البطيء الخيط: فالملفات وDNS والتجزئة تذهب إلى مجمّع libuv، ويراقب نظام التشغيل المقابس الشبكية.
- عند انتهاء العمل، تنتظر دالة رد النداء الخاصة به في طابور المهام.
- قبل المهمة التالية، تُنفَّذ كل دوال الوعود الموجودة في طابور المهام الدقيقة.
- تدور الحلقة عبر مراحلها وتأخذ المهمة التالية.
PHP وNode على خادم واحد
يستقبل Nginx كل طلب ويوجّه كل مسار إلى العملية المسؤولة عنه. يتشارك موقع PHP وخدمة Node لديك الجهاز وقاعدة البيانات والشهادة - لا ذاكرة كلٍّ منهما.
أيهما لأي عمل
نبني بالاثنين، لذا تأتي الإجابة من طبيعة العمل لا من العادة.
اختر PHP عندما
- يكون الموقع في معظمه صفحات ونماذج ولوحة إدارة: متاجر ومواقع محتوى وأنظمة أعمال.
- تريد WordPress أو WooCommerce أو Laravel وكل ما بُني لها مسبقًا.
- يكون كل طلب مستقلًا بذاته وينتهي بسرعة.
- يكون من سيتولون صيانته يعرفون PHP بالفعل.
اختر Node عندما
- تبقى الاتصالات مفتوحة: محادثات ولوحات متابعة حية وإشعارات وتتبّع.
- تُعرض صفحات React أو Vue من جهة الخادم باستخدام Next.js أو Nuxt.
- تقضي الخدمة معظم وقتها في انتظار واجهات برمجية أخرى وتمرير البيانات كتدفّق.
- تفيد فريقك لغةٌ واحدة في المتصفح وعلى الخادم.
وكثيرًا ما تكون الإجابة: الاثنان معًا
يحتفظ PHP بالموقع والمتجر ولوحة الإدارة، وتتولى خدمة Node صغيرة بجانبه الجزء الفوري. ويقرأ كلاهما من قاعدة البيانات نفسها ويعملان خلف Nginx نفسه.
إصدارات بلا انقطاع
يبدأ الإصدار الجديد بجانب القديم، ويثبت سلامته، ثم يستلم الحركة بعد ذلك فقط. وتُنهي العمليات القديمة الطلبات التي بين يديها قبل أن تتوقف.
- الزوار المخدومون
- الإصدار الحالي
- الإصدار الجديد
-
01
الجلب والتثبيت
git pull && npm ciالإصدارات نفسها المثبّتة في ملف القفل، ولا شيء أحدث على سبيل المفاجأة.
-
02
البناء
npm run buildتُترجَم شيفرة TypeScript والملفات الثابتة قبل إعادة تشغيل أي شيء.
-
03
التشغيل بجانب القديم
pm2 reload appيبدأ الإصدار الجديد بجانب الإصدار الذي لا يزال يخدم الزوار.
-
04
الانتظار حتى الجاهزية
wait_ready: trueيجب أن يجتاز فحص السلامة قبل أن يستقبل أي زائر.
-
05
استلام الحركة
cluster → new workersتتجه الاتصالات الجديدة إلى الإصدار الجديد.
-
06
تصريف القديم
SIGINT → server.close()تُنهي العمليات القديمة الطلبات التي بين يديها، ثم تتوقف.
الخادم من حول الشيفرة
كل ما يُبقي خدمة Node قائمة مكتوب على الخادم، في ملفات نتولى صيانتها ويمكنك قراءتها.
-
/etc/nginx/sites-enabled/app.confالوكيل العكسي
التشفير عبر TLS، والضغط، وتخزين الملفات الثابتة مؤقتًا، وترقية اتصالات WebSocket، أمام كل عملية.
-
/srv/app/ecosystem.config.jsمدير العمليات
يُبقي PM2 العملية حيّة، ويعيد تشغيلها إذا تعطلت، ويستخدم كل أنوية المعالج في وضع العنقود. وحيث تكفي عملية واحدة، تؤدي وحدة systemd المهمة نفسها.
-
/srv/app/.env (0600)البيئة والأسرار
تُحفظ المفاتيح وكلمات المرور خارج الشيفرة وخارج git، ولا يقرؤها إلا مستخدم التطبيق نفسه.
-
/srv/app/package-lock.jsonتدقيق الاعتماديات
فحص npm audit مع كل إصدار؛ وتُقرأ الترقيات وتُختبر قبل أن تصل إلى بيئة الإنتاج.
-
/srv/app/.nvmrcالترقية بين إصدارات Node LTS
يعمل التطبيق على إصدار ذي دعم طويل الأمد، وننقله إلى الإصدار التالي قبل أن ينتهي دعم الإصدار القديم.
-
/var/log/app/السجلات والمراقبة
سجلات منظّمة تُدوَّر بانتظام، مع تنبيه عند إعادة تشغيل العملية أو ارتفاع استهلاك الذاكرة أو تزايد الأخطاء.
أربعة أرقام وراء كل خدمة Node
كل رقم مأخوذ من توثيق Node.js أو libuv أو WebSocket، لا من قياساتنا نحن، فيمكنك التحقق منه عند مصدره.
-
30شهرًا
من الإصلاحات لكل إصدار Node.js من فئة LTS: 12 شهرًا من الدعم النشط ثم 18 شهرًا من الصيانة.
المصدر: مجموعة عمل إصدارات Node.js
-
4خيوط
في مجمّع libuv افتراضيًا، للملفات وDNS والتجزئة. ويمكن رفع حجم المجمّع بإعداد واحد حتى 1024.
المصدر: توثيق libuv
-
101رمز الحالة
هو رد الخادم على طلب التحويل إلى WebSocket: Switching Protocols.
المصدر: RFC 6455
-
443منفذ
هو المنفذ الذي يتصل به WebSocket الآمن افتراضيًا، وهو نفسه منفذ HTTPS، فيحمل مدخل Nginx الواحد الاثنين معًا.
المصدر: RFC 6455
ما تستطيع خدمة Node فعله في لمحة
القدرات في أربع مجموعات: ما تقدّمه، وما تحيله إلى غيرها، وأين تحفظ بياناتها، وكيف تبقى شغّالة.
البناء والتقديم
-
واجهات HTTP وREST
Express وحده، أو NestJS الذي يعمل فوق Express افتراضيًا ويمكنه استخدام Fastify بدلًا منه.
-
TypeScript
عقود محددة الأنواع بين الوحدات، يُتحقق منها عند بناء الشيفرة، قبل إعادة تشغيل أي شيء.
-
العرض من الخادم
يعرض Next.js وNuxt الصفحات على الخادم، فيحصل محرك البحث والزائر لأول مرة على HTML جاهز.
-
الوقت الفعلي
يبدأ Socket.IO عبر HTTP العادي ثم يرتقي إلى WebSocket، فيتصل حتى حيث يمنع وسيط WebSocket، ويعيد الاتصال من تلقاء نفسه.
إحالة العمل الثقيل
-
خيوط العمل (Worker threads)
شيفرة JavaScript الثقيلة على المعالج تعمل في خيوطها الخاصة وتترك حلقة الطلبات حرة. تفيد في الحساب، لا في انتظار عمليات الإدخال والإخراج.
-
طوابير على Redis
تُوضع المهام البطيئة في طابور وتُنجز في الخلفية بعيدًا عن طلب الزائر.
-
مهام مجدولة
مهام تعمل في أوقات محددة بدل انتظار زائر يشغّلها.
-
وضع الكتلة (Cluster)
يشغّل PM2 عاملًا لكل نواة، فتستفيد الخدمة المزدحمة من الجهاز كله بدل خيط واحد منه.
البيانات قريبة
-
MySQL وPostgreSQL
يمكن لخدمة Node وموقع PHP قراءة قاعدة البيانات نفسها.
-
Redis
الجلسات والتخزين المؤقت والطوابير في الذاكرة، ومشتركة بين البيئتين.
-
الملفات الثابتة
يقدّم Nginx ملفات CSS والصور والتنزيلات مباشرة من القرص، فلا تتولى Node إلا ما يحتاج إلى شيفرة.
-
خطة نسخ احتياطي واحدة
خطة نسخ احتياطي واحدة تغطي موقع PHP وخدمة Node معًا.
الاستمرار والتحديث
-
إعادة التشغيل عند العطل
يعيد PM2، أو وحدة systemd حيث تكفي عملية واحدة، تشغيل العملية التي تعطلت.
-
إعادة التحميل دون انقطاع
يجتاز الإصدار الجديد فحص السلامة قبل أن يستلم أي حركة.
-
سجلات وتنبيهات
سجلات منظّمة تُدوَّر دوريًا، وتنبيه عند إعادة تشغيل العملية أو ارتفاع الذاكرة أو زيادة الأخطاء.
-
إصدارات LTS والتدقيق
إصدار Node بدعم طويل الأمد، وتشغيل npm audit مع كل إصدار، وأسرار محفوظة خارج الشيفرة.

أخبرنا بما يجب أن يؤديه تطبيق Node لديك
خدمة جديدة، أو موقع Next.js، أو تطبيق يعمل في مكان ما ويحتاج إلى بيئة لائقة. ننظر فيه ونقدّم عرض السعر بعد محادثة قصيرة.