STACK://UP الأقاليم 0/9RTL · AR / قفز · ? اختصارات UP

الإقليم ١ — داخل الصندوق الواحد: LAMP وتقسيم الأدوار

النبذة

وصل الطلب إلى 8.8.8.8. في الإقليم السابق رأينا الخادم دوراً لا صندوقاً — والآن نفتح الصندوق ونكتشف أنه يحمل عدّة أدوار تتعاون. هذا هو قلب Task 0: «خادمٌ واحد يشغّل web server و application server و application files و database». السؤال الذي يقودنا: لماذا أربعة أشياء؟ لماذا لا برنامجٌ واحدٌ يفعل كل شيء؟

اللغز المستفزّ

عندك ملفٌّ ثابت logo.png وصفحةٌ تعرض اسم المستخدم الحالي مأخوذاً من قاعدة البيانات. كلاهما يصل عبر نفس الـ HTTP، نفس الـ port. ومع ذلك، في كل بنيةٍ حقيقية، يخدمهما برنامجان مختلفان: واحدٌ يسلّم logo.png، وآخرُ يولّد صفحة الاسم.

لماذا؟ ما الفرق الجوهري بين «سلّم ملفاً موجوداً» و«ولّد صفحةً لم تكن موجودة»؟ ولو أجبرتَ برنامجاً واحداً على الاثنين، ما الذي ستخسره؟ فكّر قبل أن تكمل — الجواب يفسّر كل تقسيمٍ لاحقٍ في هذا المنهج.

الدرس

ليش نفصل: ملفٌّ جاهز مقابل صفحةٍ تُحسَب

الفرق الجوهري ليس في HTTP، بل في مصدر المحتوى:

هاتان طبيعتان متناقضتان: الأولى تريد سرعةً وبساطةً وصلابة؛ الثانية تريد مرونةً وقدرةً على تشغيل لغةٍ كاملة. حشرهما في برنامجٍ واحدٍ يعني أن البرنامج الذي يكشف وجهه للإنترنت (سطح الهجوم) هو نفسه الذي يشغّل منطقك ويلمس قاعدة بياناتك. الفصل يجعل كل طرفٍ يتقن دوره — وهذا مبدأ فصل الاهتمامات (separation of concerns) الذي سيصير لاحقاً مبدأ التوسّع (الإقليم ٧).

الأدوار الثلاثة (+ الكود) داخل صندوق Task 0

١) Web server — مثال Nginx. أول من يستقبل HTTP من الإنترنت. مهامه:

٢) Application server — مثال Gunicorn / uWSGI / PHP-FPM. يشغّل كودك فعلياً: يستقبل الطلب الممرَّر من Nginx، ينفّذ منطق التطبيق (يقرأ/يكتب في قاعدة البيانات، يطبّق القواعد)، ويعيد صفحةً مولَّدة. هو من يفهم منطق تطبيقك؛ Nginx لا يفهمه.

٣) Application files — قاعدة الكود (codebase). ليست خادماً، بل ما ينفّذه الـ application server: ملفّاتك (Python/PHP/…)، القوالب، الإعدادات. الـ app server محرّك؛ هذه هي الوقود.

٤) Database — مثال MySQL. خادمٌ آخر يحفظ الحالة (state): البيانات التي تبقى بين الطلبات (مستخدمون، طلبات، محتوى). الـ application server يسأله عبر استعلام (SQL query)، فيعيد البيانات. لماذا منفصلٌ عن الكود؟ لأن الحالة تحتاج معاملةً خاصة (ثبات، نسخ احتياطي، تكامل) — وستكتشف في الإقليم ٤ أنها أصعب جزءٍ تكاثره.

تتبّع طلبٍ ديناميكيٍّ واحدٍ خلال الصندوق

ارسمها في ذهنك الآن (وستعيد رسمها على السبورة):

المستخدم ──HTTP──▶ Nginx (web server) │ static? ── نعم ──▶ يردّ الملف مباشرةً ─────────────┐ │ dynamic? ── نعم ──▶ يمرّر الطلب │ ▼ │ App server (ينفّذ codebase) ──SQL──▶ MySQL ──rows──▶ App │ │ │ ▼ يبني الصفحة ويعيدها لـ Nginx ───────────────────────┘ المستخدم ◀──HTTP── Nginx (يعيد الجواب)

كل سهمٍ هنا بروتوكول أو واجهة. على السبورة، سمِّ كل سهم. هذه الرسمة هي نواة Task 0 كلها.

ليش الاسم LAMP — وفخّ Nginx

المشروع يطلب أن تعرف الاختصار LAMP:

لكن انتبه للفخّ: مشروعك يستخدم Nginx لا Apache. الـ stack الذي web server فيه Nginx يُسمّى تقليدياً LEMP (الـ E من «engine-x»). لا تقل «LAMP» وأنت ترسم Nginx دون أن تعي الفرق؛ لو سُئلت، اذكر أنك تعرف الاختصار LAMP، وأن استبدال Apache بـ Nginx يجعله LEMP. معرفة لماذا تختلف الحروف تُظهر أنك تفهم الأدوار لا الحروف.

تحليل الأخطاء: ثلاثة أوهامٍ شائعة

التمرين (سبورة)

أنجِز مخطّط Task 0 كاملاً على ورقة، ثم اكتب بجانب كل عنصرٍ جملةً واحدةً تجيب عن سؤال المشروع المقابل:

  • ما دور domain name؟ ما نوع سجلّ www (من الإقليم ٠)؟
  • ما دور web server؟ ما دور application server؟ ما دور database؟
  • بأي شيءٍ يتواصل الخادم مع جهاز المستخدم؟

ثم — وهذا الأهم — اكتب تحت المخطّط ثلاث مشاكل في هذه البنية. لا تقرأ القسم التالي قبل أن تحاول استخراجها بنفسك من العدسة: «ما الذي يُسقط هذا النظام؟».

بذرة الانهيار: لماذا هذا الصندوق الأنيق قنبلةٌ موقوتة

المشروع يطلب أن تشرح مشاكل هذه البنية. لاحظ أنها كلها تنبع من حقيقةٍ واحدة: كل شيءٍ في صندوقٍ واحد.

هذه الثلاث ليست عيوباً متفرّقة — هي عَرَضٌ واحدٌ: التفرّد. كل ما تبقّى من المنهج هو تفكيك هذا التفرّد. لكن أول ما يجب أن نسمّيه ونفهمه بدقّةٍ هو الوحش المركزي: SPOF. وهذا هو الإقليم ٢.

الخلاصة — وصلٌ في الشجرة


على السبورة (إنجليزي، مكثّف)

Inside the one server, roles are separated:

  • Web server (Nginx): receives HTTP, serves static files, and reverse-proxies

dynamic requests to the app server.

  • Application server: runs my codebase to generate dynamic pages.
  • Application files (codebase): the code the app server executes.
  • Database (MySQL): stores persistent data; the app queries it over SQL.

This is a LAMP stack (Linux/Apache/MySQL/PHP) — with Nginx instead of Apache it's technically LEMP.

Problems: it's a SPOF (server dies → whole site down); downtime on maintenance (restarting/deploying takes the site offline); and can't scale beyond this one machine's capacity.

وقفة الانضباط: الفرق بين web و app server يُجاب في جملتين (يخدم static + يمرّر / يشغّل الكود). لا تشرح PHP-FPM أو WSGI ما لم يُطلب.