English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

ضيف
1 / ?

اتجاهان لحركة المرور، صندوق واحد

مرحباً

تُظهر معظم المخططات المعمارية حركة المرور باتجاه واحد: العميل في الأعلى، والخادم في الأسفل، والسهم يشير إلى الأسفل. لكن الواقع يتضمن حركة مرور باتجاهين.

حركة الدخول (Ingress): تصل العملاء الخارجية إلى خدماتك عبر هذا المسار. يقوم وكيل عكسي (Reverse Proxy) على حافة شبكتك بإنهاء TLS، وتوجيه الطلبات، وتطبيق سياسة الوصول.

حركة الخروج (Egress): تصل خدماتك إلى الخدمات الخارجية عبر هذا المسار. استدعاء واجهة برمجة التطبيقات (API) لمعالج المدفوعات، أو جلب هدف Webhook، أو إرسال طلب إلى شريك. غالباً عبر وكيل أمامي (Forward Proxy) أو بوابة NAT مع قائمة سماح.

تبدأ العديد من البنى المعمارية بصندوق واحد يتعامل مع كلا الاتجاهين. يعمل هذا الحل، حتى اليوم الذي يتوقف فيه عن العمل. يكون نمط الفشل خفيًا، ولا يظهر إلا بعد أن يصبح عدد الخدمات الداخلية كافٍ، ويدرّس درسًا مهمًا حول فصل الاهتمامات.

بحلول نهاية هذا الدرس، ستفهم:

- لماذا يمثل كل من الدخول (Ingress) والخروج (Egress) أنماط حركة مرور مختلفة جذريًا، مع محاور توسع مختلفة وأنماط فشل مختلفة

- NAT المنحني (Hairpin NAT) ولماذا يفشل وكيل (Proxy) يحاول الاتصال بنفسه

- التفرع المعماري: كيف يتحول صندوق واحد إلى صندوقين، وما الذي يملكه كل منهما حصريًا بعد ذلك

- المكاسب في العزل الأمني: يمكن لكل جانب أن يقفل الوصول على أقرانه المسموح بهم فعليًا فقط

- كيفية تحديد اللحظة التي يعبر فيها تصميمك المصمم على صندوق واحد العتبة التي يصبح عندها التقسيم ضروريًا

لماذا تتطلب الاتجاهات أدوات مختلفة

حمّلتان عمل مختلفتان عند حدّ الشبكة الواحد

خصائص حركة المرور الواردة (Ingress):

- تُبدأ من أطراف خارجية (الإنترنت بشكل عام)

- حجمها يتناسب مع حجم قاعدة المستخدمين لديك

- إنهاء TLS، توجيه الطلبات، وتحديد معدل الطلبات لكل مصدر

- مخاوف تتعلق بالدفاع متعدد الطبقات: هجمات حجب الخدمة الموزعة (DDoS)، إساءة الاستخدام، والحصاد (Scraping)

- يجب أن يقبل عنوان IP العام الاتصالات من أي شخص

خصائص حركة المرور الصادرة (Egress):

- تُطلقها خدماتك الخاصة (مجموعة معروفة وصغيرة من العملاء)

- الحجم يتناسب مع أنماط استدعاءات الخدمة إلى الخدمة وواجهات API الخارجية لديك

- السماح بقوائم عناوين IP المصدرية في نقاط النهاية البعيدة (لديك عنوان IP خارجي ثابت تثق به الشراكات)

- مخاوف الدفاع متعدد الطبقات: تسرب البيانات، وخدمات داخلية مخترقة تقوم بالاستدعاء للخارج

- يجب رفض الاتصالات من أي شخص غير خدماتك الخاصة

عدم التماثل الرئيسي: يستقبل الدخول (Ingress) حركة المرور من العالم؛ بينما يستقبل الخروج (Egress) حركة المرور فقط من خدماتك الخاصة. وضعهما على نفس الجهاز يعني أن هذا الجهاز يجب أن يكون قابلاً للوصول من العالم (للدخول) وقابلاً للوصول فقط من خدماتك (للخروج) في نفس الوقت. قواعد الجدار الناري التي تحقق شرطاً تعمل ضد الآخر.

مسار النمو: يمكن لمشروع صغير إخفاء كلا الدورين خلف عنوان IP واحد وأداة واحدة، لأن الحجم صغير وقائمة عناوين IP للشركاء قصيرة. ومع نمو المشروع، تزداد الاحتكاكات بين الدورين، وفي يوم ما يجبر نمط فشل محدد (NAT hairpin) على الفصل بينهما.

الدخول مقابل الخروج: مصادر مختلفة، وجهات مختلفة، متطلبات مختلفة

شركة ناشئة صغيرة تشغّل كل شيء (وكيل عكسي للمدخلات، وكيل أمامي للمخرجات / NAT، الخدمات الداخلية) على خادم افتراضي واحد مع عنوان IP عام واحد. هم في مرحلة مبكرة بحيث يبدو هذا مقبولاً. اذكر وضعَي فشل محددين أو مشكلتين تشغيليتين ستواجههما هذه البنية مع نمو الشركة، ولأحدهما، اشرح السبب الجذري.

الخطأ الذي يفرض الفصل

قصة انقطاع معقّمة

تخيّل تشعّبًا معماريًا حقيقيًا يحدث في أساطيل الإنتاج. تم تغيير الأسماء أدناه؛ والشكل مطابق تمامًا لما تواجهه الفرق في الواقع العملي.

تشغّل منظمةً خادم وكيل واحدًا على 203.0.113.5. يتعامل هذا الخادم مع الدخول (المنفذ 443 للمستخدمين) والخروج (المنفذ 1080 بروتوكول SOCKS5 للخدمات الداخلية التي تستدعي خدمات خارجية). توجد الخدمات الداخلية في شبكات فرعية خاصة وتوجّه جميع حركة المرور الخارجة عبر وكيل SOCKS5 على 203.0.113.5:1080.

إحدى الخدمات المستضافة خلف نفس 203.0.113.5 هي api.example.com. يحلّ DNS العام api.example.com إلى 203.0.113.5.

الآن تحتاج خدمة داخلية مختلفة إلى استدعاء api.example.com. مسارها الخارج:

1. تحلّ الخدمة الداخلية api.example.com إلى 203.0.113.5

2. ترسل الخدمة الداخلية الطلب عبر وكيل الخروج SOCKS5 على 203.0.113.5:1080

3. يحاول الوكيل فتح اتصال من نفسه إلى 203.0.113.5:443

4. تم رفض الاتصال. كان على الحزمة أن تغادر NAT وتعود إلى نفس الـ NAT، وهو ما ترفضه معظم أكوام الشبكات. لا يمكن للوكيل (Proxy) الاتصال بنفسه عبر عنوانه العام.

هذا هو NAT منحنى الشعر (Hairpin NAT): حزمة تغادر NAT وتحتاج إلى إعادة الدخول إلى نفس الـ NAT للوصول إلى وجهتها. بدون دعم خاص لمنحنى الشعر في طبقة التوجيه، يتم إسقاط الحزمة.

لماذا يظهر متأخرًا

في المراحل المبكرة من حياة المشروع، كان كل خدمة داخلية إما تتحدث إلى خدمات داخلية أخرى عبر اسم المضيف الخاص (internal-api.local) أو لم تكن تستدعي خدماتها العامة الخاصة. ببساطة، لم يكن مسار منحنى الشعر موجودًا.

ثم تطلبت ميزة جديدة أن تستدعي الخدمة A عنوان api.example.com (اسم مضيف عام). تم تفعيل مسار منحنى الشعر. تم رفض الاتصال. انقطاع في الخدمة.

أصلح الإصلاح العرض (إجبار محلل الأسماء على إعطاء عنوان IP الخاص لـ api.example.com بدلاً من العام). السبب الجذري: صندوق واحد كان يؤدي مهامًا كثيرة جدًا.

NAT منحنى الشعر: الحزمة تغادر ولا تستطيع إعادة الدخول إلى نفس الـ NAT

التشعب المعماري

صندوق واحد يصبح اثنين

الحل النظيف: فصل الوسيط إلى جهازين.

خادم الدخول (عنوان IP عام 203.0.113.5):

- كادي / وكيل عكسي على المنافذ 80، 443

- سجلات DNS العامة تشير إلى هنا

- يستضيف api.example.com، app.example.com، وما إلى ذلك.

خادم الخروج (عنوان IP عام مختلف 203.0.113.99):

- SOCKS5 / وكيل أمامي على المنفذ 1080

- يقيد جدار الحماية الاتصالات الواردة فقط إلى عناوين IP الداخلية للشبكة الفرعية

- توجيه الخدمات الداخلية لجميع الاتصالات الصادرة عبر هذا العنوان

ما الذي يحققه ذلك:

1. حل مشكلة Hairpin. عندما تستدعي خدمة داخلية api.example.com، يتم توجيه الاتصال الصادر عبر 203.0.113.99 (إخراج)، ثم يتصل بشكل طبيعي بـ 203.0.113.5 (إدخال، وهو عنوان IP مختلف). يختفي حلقة NAT لأن العنوانين IP موجودان على جهازين مختلفين.

2. عزل الأمان. يمكن لجدار حماية خادم الإخراج (Egress) أن يقيد الوصول إلى مجموعة صغيرة من عناوين IP الداخلية. بينما يبقى جدار حماية خادم الإدخال (Ingress) مفتوحًا للعالم. مجموعتا قواعد منفصلتان، كل منهما تعبر عن دور واحد بوضوح.

3. توسع مستقل. تتوسع سعة الإرسال والاستقبال (Bandwidth) للإدخال مع عدد المستخدمين؛ وتتوسع سعة الإخراج مع نشاط الخدمات الداخلية. يمكنك ترقية أحدهما دون التأثير على الآخر.

4. عزل الأعطال. لم يعد الخلل في إعدادات الإخراج (Egress) يكسر الموقع العام. ولم يعد هجوم الحرمان من الخدمة (DDoS) الموجه ضد الموقع العام يستنزف سعة الإخراج.

5. نموذج ذهني أوضح. لكل جهاز وظيفة واحدة. يفكر المهندسون في مخاوف الإدخال (Ingress) دون التفكير في الإخراج (Egress)، والعكس صحيح.

بعد التقسيم، لا يزال هناك حاجة لخدمة داخلية للاتصال بـ `api.example.com`. اشرح مسار الحزمة الجديد من الخدمة الداخلية إلى الخلفية (Backend) الخاصة بالـ API. يتضمن ذلك: أي عنوان IP تتصل به الخدمة الداخلية أولاً، وما الذي تفعله تلك الآلة بالطلب، وأي عنوان IP ترسل إليه الطلب التالي، وإلى أين تذهب الاستجابة.

محوران، وقراران لتحديد الحجم

التوسع المستقل

قبل الفصل، كان النمو في أي اتجاه يُشكّل ضغطاً على نفس الخادم. بعد الفصل، أصبح لكل اتجاه تخصيصه الخاص.

حجم الدخول (Ingress): يتوسع مع عدد المستخدمين. وتقع قرارات السعة في الطبقة الموجهة للجمهور (عدد أكبر من نسخ وكيل العكس، خوادم افتراضية أكبر، شبكة توزيع محتوى CDN في المقدمة). ويتم حساب ميزانية النطاق الترددي بناءً على حركة مرور المستخدمين في ذروة الاستخدام.

حجم الخروج (Egress): يتوسع مع حجم استدعاءات الخدمات الداخلية إلى واجهات برمجة التطبيقات الخارجية. وغالباً ما يكون مهيمناً عليه تسليم أوامر الاستدعاء (Webhooks)، أو استدعاءات معالج الدفع، أو عمليات جلب البيانات من أطراف ثالثة. ويتم حساب ميزانية النطاق الترددي بناءً على أنماط الاستدعاء الداخلية.

عزل الأعطال: لم يعد هجوم الحرمان من الخدمة الموزع (DDoS) الموجّه إلى نقطة الدخول العامة يستهلك نطاق الخروج (إذ أن استدعاءات معالج الدفع تتم على أي حال). ولم يعد تعطل وكيل الخروج (Egress proxy) يسقط الموقع العام (فالمستخدمون يواصلون الوصول إلى الموقع؛ بينما تفشل فقط الاستدعاءات الصادرة الداخلية).

أهداف مستوى الخدمة (SLOs) المختلفة: تهم توافر الدخول (Ingress) المستخدمين (انقطاع الموقع المرئي)؛ بينما يهم توافر الخروج (Egress) المشغلين (أعطال في الخلفية قد يستغرق اكتشافها وقتاً أطول). ويمكن لكل جانب أن يحمل هدف مستوى خدمة خاصاً به.

خوادم خروج متعددة

بمجرد أن يصبح دور الخروج (Egress) على خادم مستقل، يصبح التحرك الواضح التالي هو تشغيل عدة خوادم خروج خلف موزّع الأحمال (Load Balancer) لضمان التوفر العالي (HA). ويشير كل خدمة داخلية جديدة إلى اسم مضيف الخروج (الذي يُحل إلى مجموعة موزّعة الأحمال) بدلاً من عنوان IP واحد.

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

تكامل شريك جديد

تنظّم مؤسستك فصل الدخول / الخروج كما هو مصمم. يملك خادم الخروج عنوان IP عام ثابت (203.0.113.99) قمت بإدراجه في قائمة السماح مع ثلاثة واجهات برمجة تطبيقات (APIs) لشركاء حاليين (معالج مدفوعات، بوابة رسائل نصية، ومزود بريد إلكتروني).

تريد فريق المنتج إضافة تكامل رابع: نظام تسليم ويب هوك (Webhook) يستدعي نقاط النهاية (endpoints) للعملاء حول العالم. التنبؤ بالحجم: 10,000 مكالمة في الدقيقة، مع ذروات تصل إلى 30,000.

قرر: هل ينتمي هذا التكامل الجديد إلى خادم الخروج الحالي، أم يحتاج إلى مسار خروج منفصل؟ راجع المنطق حول النطاق النطاق الترددي (Bandwidth)، وعزل الأعطال، وما إذا كانت قوائم السماح للشركاء الحاليين بحاجة إلى تحديث في أي من الحالتين.

تصميم حدّ شبكة لخدمة متنامية

التوليف

لقد تعلّمتَ لماذا تتطلب حركة الدخول (Ingress) وحركة الخروج (Egress) أدوات مختلفة، وفشل NAT المنحني (Hairpin NAT) الذي يفرض الفصل في الأساطيل الحقيقية، وكيفية تحقيق التوسع المستقل، والعزل الأمني، وعزل الأعطال بمجرد إتمام الفصل.

طبّق جميع العناصر الأربعة.

شركة SaaS متوسطة الحجم تشغّل ثلاثة نطاقات فرعية للمنتجات (app، api، admin) لمستخدميها، بالإضافة إلى أربعة تكاملات خارجية (Stripe، Twilio، SendGrid، ونظام Webhook للعملاء). اليوم، كل شيء يعمل خلف جهاز وكيل (Proxy) واحد على عنوان IP عام واحد. لقد بدأوا في تلقي تقارير عن أعطال متقطعة في NAT المنحني (Hairpin) عندما تحاول الخدمات الداخلية الاتصال بـ api.example.com. يريدون تصميم حل دائم.

اقترح معمارية دخول / خروج (Ingress / Egress) لهذه الشركة. عالج: عدد الأجهزة، أي عناوين IP تؤدي أي أدوار، أين يشير DNS لكل نطاق فرعي، أي تكاملات خارجية (Outbound integrations) تشارك مسار خروج واحد (وأي منها يجب فصله)، وواحد من مخاوف المراقبة المحددة التي تتيحها التصميم الجديد ولم تكن ممكنة في التصميم القديم.

إلى أين يتجه هذا المساق بعد الآن

إلى أين يتجه هذا المساق بعد الآن

لقد رأيت الآن الآن أحد أعيدات هيكلة فصل الاهتمامات (Separation-of-concerns) الأنظف في الأنظمة الموزعة: صندوق واحد يصبح صندوقين، لكل منهما دور واضح، ويزاوج النظام فوائد التوسع والأمان وعزل الأعطال على طول الطريق.

توسّع الدرس التالي (cs_distsys_failure_modes_and_blast_radius) في استنتاجات عزل الأعطال. ستقرأ تقريراً بعد الحادث (Postmortem) معقّمًا لخطأ DNS-SERVFAIL، وتحدد نمط الفشل المتسلسل، وتكتب عناصر إجراء خالية من اللوم تستهدف الأنظمة بدلاً من الأشخاص.

درس مرافق: يعيد geometry_of_ingress_egress_separation صياغة الفصل كرسوم ثنائية (Bipartite Graph) ويستكشف رؤوس القطع (Cut Vertices) وتقسيمات الشبكة، وما تخبرك به نظرية الرسوم البيانية عن حدود الشبكة.

أحسنت. إلى الأمام.