تطبيقات Node.js

Node.js، نبنيه ونشغّله بجانب PHP لديك.

نبني بـ Node واجهات برمجية، ومواقع تُعرض من الخادم، وخدمات فورية، وعمّالًا في الخلفية، ونشغّلها على الخوادم نفسها التي تعمل عليها مواقع PHP لديك، خلف Nginx واحد.

ما نبنيه بـ Node

خمسة أنواع من العمل، وكل منها هنا لأن Node يناسبه.

  1. 01

    Express

    واجهات برمجية وخوادم خلفية صغيرة ومباشرة: مسارات قليلة، وطبقات وسيطة واضحة، ولا شيء مخفي.

    واجهات برمجية وخوادم خلفية
  2. 02

    NestJS

    خدمات أكبر مبنية على وحدات وحقن التبعيات وعقود محددة الأنواع بلغة TypeScript، لشيفرة سينمّيها فريق على مدى سنوات.

    خدمات منظّمة
  3. 03

    Next.js · Nuxt

    عرض من جهة الخادم لـ React وVue: تصل الصفحات جاهزة لمحركات البحث ولظهور أول سريع، ثم تعمل كتطبيق.

    مواقع تُعرض من الخادم
  4. 04

    Socket.IO · WebSockets

    محادثات وإشعارات ولوحات متابعة حية وتتبّع، تتحدّث لحظة حدوث أي تغيير عبر اتصال واحد مفتوح.

    الوقت الفعلي
  5. 05

    العمّال والطوابير

    مهام في الخلفية ومهام مجدولة ومستهلكو طوابير على Redis، تُبقي العمل البطيء خارج الطلب.

    العمل في الخلفية

لماذا يُجيد Node الانتظار

تشغّل عملية Node شيفرة JavaScript على خيط واحد، وتترك الانتظار - للقرص والشبكة وقاعدة البيانات - للنظام. وبهذا تُبقي عملية واحدة اتصالات كثيرة مفتوحة في آن واحد.

حلقة أحداث Node.js، بصورة مبسّطة
  1. تعمل شيفرتك على مكدّس الاستدعاءات، دالة واحدة في كل مرة.
  2. يغادر العمل البطيء الخيط: فالملفات وDNS والتجزئة تذهب إلى مجمّع libuv، ويراقب نظام التشغيل المقابس الشبكية.
  3. عند انتهاء العمل، تنتظر دالة رد النداء الخاصة به في طابور المهام.
  4. قبل المهمة التالية، تُنفَّذ كل دوال الوعود الموجودة في طابور المهام الدقيقة.
  5. تدور الحلقة عبر مراحلها وتأخذ المهمة التالية.

PHP وNode على خادم واحد

يستقبل Nginx كل طلب ويوجّه كل مسار إلى العملية المسؤولة عنه. يتشارك موقع PHP وخدمة Node لديك الجهاز وقاعدة البيانات والشهادة - لا ذاكرة كلٍّ منهما.

مثال على خادم واحد يشغّل الاثنين

أيهما لأي عمل

نبني بالاثنين، لذا تأتي الإجابة من طبيعة العمل لا من العادة.

اختر PHP عندما

  • يكون الموقع في معظمه صفحات ونماذج ولوحة إدارة: متاجر ومواقع محتوى وأنظمة أعمال.
  • تريد WordPress أو WooCommerce أو Laravel وكل ما بُني لها مسبقًا.
  • يكون كل طلب مستقلًا بذاته وينتهي بسرعة.
  • يكون من سيتولون صيانته يعرفون PHP بالفعل.

اختر Node عندما

  • تبقى الاتصالات مفتوحة: محادثات ولوحات متابعة حية وإشعارات وتتبّع.
  • تُعرض صفحات React أو Vue من جهة الخادم باستخدام Next.js أو Nuxt.
  • تقضي الخدمة معظم وقتها في انتظار واجهات برمجية أخرى وتمرير البيانات كتدفّق.
  • تفيد فريقك لغةٌ واحدة في المتصفح وعلى الخادم.

وكثيرًا ما تكون الإجابة: الاثنان معًا

يحتفظ PHP بالموقع والمتجر ولوحة الإدارة، وتتولى خدمة Node صغيرة بجانبه الجزء الفوري. ويقرأ كلاهما من قاعدة البيانات نفسها ويعملان خلف Nginx نفسه.

إصدارات بلا انقطاع

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

  • الزوار المخدومون
  • الإصدار الحالي
  • الإصدار الجديد
  1. 01

    الجلب والتثبيت

    git pull && npm ci

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

  2. 02

    البناء

    npm run build

    تُترجَم شيفرة TypeScript والملفات الثابتة قبل إعادة تشغيل أي شيء.

  3. 03

    التشغيل بجانب القديم

    pm2 reload app

    يبدأ الإصدار الجديد بجانب الإصدار الذي لا يزال يخدم الزوار.

  4. 04

    الانتظار حتى الجاهزية

    wait_ready: true

    يجب أن يجتاز فحص السلامة قبل أن يستقبل أي زائر.

  5. 05

    استلام الحركة

    cluster → new workers

    تتجه الاتصالات الجديدة إلى الإصدار الجديد.

  6. 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 لديك

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