الإقليم ٧ — الانتشار: فصل المكوّنات وعنقود الموزّعات (Scale up)
النبذة
المراقبة نبّهتك: طبقةٌ واحدةٌ اختنقت بينما الباقي مرتاح. وبقي من الإقليم ٣ ديْنٌ لم نسدّده: الموزّع نفسه SPOF. Task 3 يسدّد الاثنين: يفصل المكوّنات (web, app, db) كلٌّ على خادمه، ويضيف موزّعاً ثانياً كعنقود. هذا هو إقليم التوسّع — حيث يصير «فصل الاهتمامات» (إقليم ١) أداةَ قياسٍ لا مجرّد تنظيم.
مراقبتك تقول: الـ app server يلهث عند ٩٠٪ CPU، بينما قاعدة البيانات على نفس الصندوق عند ٥٪. تريد طاقة app أكثر. لكن كل خادمٍ يحوي web+app+db معاً، فلإضافة app تُجبر على شراء صندوقٍ كامل بقاعدة بياناتٍ زائدةٍ لا تحتاجها — وتدفع ثمن ثلاثة لتوسّع واحداً.
كيف تعيد ترتيب البنية بحيث تستطيع أن تكاثر الطبقة المختنقة وحدها، بأقل كلفة؟ وفي الوقت نفسه، كيف تزيل كون الموزّع SPOF؟ صمّم على ورقة قبل أن تكمل.
الدرس
ليش نفصل المكوّنات على خوادمَ خاصّة
في الإقليم ٤ رأينا عيب «كل المكوّنات على كل خادم»: تنافسٌ على الموارد، واستحالة توسيع طبقةٍ وحدها. الحلّ هو إتمام فصل الاهتمامات مادّياً: web server على خادم(ات)، app server على خادم(ات)، database على خادم(ات) — كلٌّ مستقل. الأرباح:
- توسّعٌ مستقل (independent scaling): إن اختنق الـ app، أضِف خوادم app فقط، بلا قاعدة بياناتٍ زائدة. تدفع حيث تحتاج فقط.
- لا تنافس على الموارد: قاعدة البيانات الجائعة لم تعد تخنق الـ web server؛ لكلٍّ صندوقه ومُلكه من CPU/RAM/قرص.
- تخصيصٌ للعتاد: خادم قاعدة البيانات يُجهَّز بأقراصٍ سريعةٍ وذاكرةٍ كبيرة؛ خادم web يُجهَّز للشبكة. كلٌّ يُحسَّن لدوره.
هذا يجيب سؤال Task 3 «لكل عنصرٍ مضاف، لماذا أضفته»: تفصل لتوسّع وتعزل وتُحسّن.
دمج وتمييز: هذا scale up بالمعنى المعماري للمشروع (فصلٌ ثم تكثيرٌ أفقي لكل طبقة). لا تخلطه بـ scaling عمودي (صندوقٌ أكبر) — المشروع لا يطلب التمييز، لكن اعرفه: الفصل يفتح الأفقي (horizontal)، وهو ما يتوسّع فعلاً بلا سقف.
ليش عنقود الموزّعات — تسديد ديْن الإقليم ٣
أضفنا الموزّع ليزيل SPOF الخوادم، فصار هو SPOF (كل الحركة عبره). الحلّ تطبيقٌ مباشر للعدسة نفسها: كرّر الموزّع. Task 3 يضيف موزّع HAProxy ثانياً، مُعَدّاً كعنقود (cluster) مع الأول. كيف يعمل العنقود؟ الوضعان من الإقليم ٣ يعودان هنا حصاداً:
- Active-Passive: موزّعٌ نشط يأخذ الحركة، وآخر احتياط يراقبه عبر نبضٍ (heartbeat) ويحمل عنوان IP عائماً (VIP). إن سقط النشط، ينتقل الـ VIP للاحتياط (failover) فيتولّى. (هذا هو النمط الكلاسيكي لعنقود HAProxy + Keepalived.)
- Active-Active: كلا الموزّعين يأخذان حركةً (عبر توزيعٍ على مستوى DNS أو Anycast). أعقد، لكنه يستغلّ الاثنين.
بهذا، موت موزّعٍ واحدٍ لم يعد يُسقط الموقع. لاحظ أنك لم تتعلّم مفهوماً جديداً — أعدتَ استخدام Active-Passive/Active-Active على طبقةٍ جديدة. هذا هو التكرار المتباعد يعمل: نفس الفكرة، سياقٌ أعمق.
ماذا يبقى SPOF؟ (الصدق المعماري)
التوسّع لا يُنهي المطاردة، ينقلها. بعد Task 3، فكّر: خادم قاعدة البيانات الأساسي (الكاتب الواحد، إقليم ٤) لا يزال SPOF للكتابة. وقد يصير DNS أو مزوّد الشبكة SPOF. المشروع يتوقّف هنا عمداً («سنستكشف التفاصيل في مشروعٍ لاحق») — لكن مهندساً ناضجاً يعرف أين تبقى نقاط الانهيار حتى بعد أن يقول «انتهيت». هذه هي العدسة وقد صارت عادة.
تحليل الأخطاء
- «فصل المكوّنات يجعل النظام أسرع تلقائياً.» لا بالضرورة؛ يجعله **قابلاً للتوسّع المستقل** ويزيل التنافس. السرعة تأتي من توسيع الطبقة الصحيحة بعد أن أصبح ذلك ممكناً.
- «الموزّع الثاني يضاعف الطاقة.» في Active-Passive هو احتياطٌ لا طاقةٌ إضافية؛ غرضه التوفّر لا الحِمل. لا تَعِد بمضاعفة الأداء.
- «بعد Task 3 لا SPOF.» خاطئ — الكاتب الواحد في قاعدة البيانات يبقى. اعرف حدودك.
ارسم بنية Task 3: موزّعان (عنقود) أمام خوادم web، ثم خوادم app، ثم طبقة قاعدة بيانات (primary + replica)، كلٌّ في طبقته. لكل عنصرٍ مضاف اكتب «لماذا أضفته». ثم على ورقة:
- لماذا فصلتَ web/app/db؟ (توسّع مستقل + عزل + تخصيص.)
- كيف يعمل عنقود الموزّعين (Active-Passive عبر VIP/heartbeat، أو Active-Active)؟
- ما الـ SPOF المتبقّية؟ (الكاتب الواحد، وربما DNS.)
الخلاصة — وصلٌ في الشجرة
- أتممتَ فصل الاهتمامات مادّياً ⟵ توسّعٌ مستقل لكل طبقة (جواب Task 3).
- سدّدتَ ديْن الإقليم ٣ بـ عنقود موزّعات، مُعيداً استخدام Active-Active/Passive حصاداً لا تعلّماً جديداً.
- مارستَ الصدق المعماري: عرفتَ أن المطاردة تستمرّ (الكاتب الواحد يبقى SPOF).
كل القطع الآن على الطاولة: DNS، خادم، web/app/db، تكرار، موزّع، نسخ متماثل، جدار، HTTPS، مراقبة، توسّع. بقي أن نجمعها في رحلةٍ واحدة ونرويها من أولها لآخرها — وهذا هو الكابستون، ومشروع «What happens when you type google.com». الإقليم ٨.
Scaling up (Task 3): I split the components — web, application, and database each onto their own server(s) — so each tier can be scaled independently, doesn't contend for resources, and can run on hardware tuned to its role.
I also add a second HAProxy as a cluster with the first (e.g., Active-Passive with a floating VIP and heartbeat: the standby takes over via failover if the active LB dies) — removing the load balancer as a SPOF.
Remaining SPOF: the single write-capable database Primary (and potentially DNS) — to be addressed later.
وقفة الانضباط: لكل عنصرٍ سطرٌ واحدٌ عن «لماذا». المشروع يطلب التبرير لا المحاضرة.