عندما يتوقف البروكسي: اختبار العزل والتعافي دون تسريب الاتصال

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

دليل عملي

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

--- title: عندما يتوقف البروكسي: اختبار العزل والتعافي دون تسريب الاتصال ---

تتناول هذه المادة تجربة تكامل أُجريت على تطبيق قائم على Electron و Chromium داخل بيئة اختبار شبكات محلية مملوكة. السؤال العملي الذي حرّك التجربة كان محدّدًا: ماذا يحدث لطلب شبكي عندما يتوقف البروكسي الذي تعتمد عليه جلسة معيّنة، وهل يبقى مسار الجلسة الأخرى مستقلًا عنه؟ لا تناقش التجربة أداء البروكسي ولا تقارن بين مزوّدين، بل تراقب سلوك المسار في لحظة الانقطاع. انتهت إلى سبعة فحوص ناجحة من سبعة، دون أخطاء في تقرير التجربة النهائي. غير أن هذا الرقم لا يعني تغطية كل مسارات الشبكة، ولذلك يفصل المقال بين ما قيس فعلًا وما لم يقس.

ما الذي جرى في التجربة

جُهّز بروفايلان افتراضيان، alpha و beta، داخل جلسات مستقلة باستخدام Session Partition، بحيث تحتفظ كل جلسة بحالتها الشبكية الخاصة. لكل بروفايل Cookie مصطنع، وبروكسي محلي اختباري مستقل، وخادم Echo محلي يستقبل الطلبات. كان خادم Echo يعيد ترويسة تعريف خاصة تربط الطلب بالبروكسي الذي وصل عبره وبالكوكي المرافق، وهو ما يجعل الطريق الفعلي قابلًا للفحص من جهة الاستقبال بدل الاعتماد على مؤشرات الواجهة.

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

الاتصال المباشر والاتصال عبر بروكسي

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

الخطر العملي يبدأ عندما ينقطع البروكسي فيقرر التطبيق، بصمت، أن يكمل الطلب مباشرة. هنا لا يتوقف الطلب، لكنه يخرج من هوية مختلفة عن التي يفترضها المستخدم أو السياسة. لهذا فإن السؤال في اختبار العزل ليس «هل نجح الطلب؟» فقط، بل «من أي مسار نجح؟». التجربة الحالية ركّزت على هذا السؤال الأخير.

سياسة الطوارئ: تعريف مسبق لا ارتجال

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

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

Fail-Closed و Auto Fallback

Fail-Closed يعني أن الطلب يفشل عندما لا يتوفر المسار المطلوب، بدل أن يخرج بمسار بديل. هذا مناسب عندما يكون ضمان هوية الخروج جزءًا من العقد: تقارير، جلسات إدارية، أو أي عمل يفترض أن الحركة تمر عبر نقطة محددة. الفشل هنا إشارة صحيحة، لأنه يمنع تسريبًا صامتًا كان سيبدو نجاحًا.

Auto Fallback يعني التحويل إلى مسار آخر عند تعذر الأول. قد يكون مطلوبًا عندما تكون الاستمرارية أهم من ثبات هوية الخروج، لكنه لا يجوز أن يحدث ضمنيًا في سياق يبني قراراته على تلك الهوية. يحتاج إذنًا أو سياسة صريحة، وإعلامًا واضحًا، وتسجيلًا للتحويل. الخلاصة أن السؤال ليس أي السلوكين أفضل، بل أي السلوكين مصرّح به في هذا البروفايل وهذه المهمة. التجربة أثبتت Fail-Closed لطلب واحد محدد، ولم تختبر Auto Fallback ولا التبديل إلى بروكسي آخر.

العزل بين البروفايلات

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

لكن العزل أوسع من هذه الملاحظة. فهو يشمل عدم تسرّب الكوكي بين الجلسات، وعدم إعادة استخدام اتصال أو ذاكرة تخزين مؤقت من جلسة في أخرى، وعدم انحراف طلبات جلسة إلى إعداد جلسة مجاورة. التجربة الحالية لم تقس هذه الجوانب كلها؛ ما قاسته هو أن تعطل مسار لم يدفع الجلسة الأخرى إلى مسار خاطئ، وأن الجلسة المتأثرة لم تنتقل إلى اتصال مباشر بحسب ما رُصد.

الدليل من الطرف المستقبل

من السهل أن تعرض الواجهة اسم بروكسي أو حالة «متصل»، لكن ذلك لا يثبت الطريق الذي سلكه الطلب. اسم البروكسي في الواجهة قد يكون قديمًا، أو يعبّر عن إعداد محفوظ لا عن مسار فعلي. الحكم الموثوق يأتي من الطرف المستقبل: خادم Echo في هذه التجربة أعاد ترويسة تعريف تجمع بين بصمة البروكسي والكوكي، فصار من الممكن معرفة ما وصل فعلًا لا ما كان مفترضًا.

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

أثناء الانقطاع وبعد العودة

أُوقف خادم بروكسي alpha محليًا أثناء الاختبار، مع إبقاء beta متاحًا. أثناء العطل فشل طلب session.fetch من alpha فعليًا، وهو سلوك Fail-Closed، ولم يُرصد انتقاله إلى اتصال مباشر. في المقابل استمر الطلب الصادر من beta في الوصول إلى خادم التجربة عبر بروكسي beta الصحيح. بعد إعادة تشغيل البروكسي الأول على نفس نقطة الوصول، عاد session.fetch الخاص ب ـalpha للعمل، ونجح أيضًا فتح صفحة عبر BrowserWindow مرتبط بالجلسة الأولى.

سُجّلت النتيجة النهائية سبعة فحوص ناجحة من سبعة، دون أخطاء في التقرير. هذه النتيجة تغطي ما جرى في هذه الجلسات وفي هذه اللحظات، لكنها لا تتحول إلى ضمان عام لكل مسارات الشبكة في التطبيق. الفصل بين «الطلب فشل كما ينبغي» و«كل مسارات التطبيق تفشل كما ينبغي» هو الفصل الذي يحمي الاختبار من المبالغة.

حدود الاستنتاج: ما لم تقسه التجربة

في الجولة الأولى لم يكن لدينا تقرير مكتمل عن فشل تحميل صفحة BrowserWindow أثناء توقف البروكسي؛ فقد أثبتت تلك الجولة فقط سلوك session.fetch واستمرار الجلسة الأخرى. لهذا كان من الضروري فصل اختبار التنقل داخل النافذة عن الطلبات المباشرة، بدل تعميم نتيجة مسار اتصال واحد على بقية المسارات. أُجري اختبار منفصل لاحقًا لهذا الغرض، وترد نتيجته أدناه.

كذلك لم تختبر التجربة سياسة Auto Fallback ولا واجهة التحكم ولا التبديل إلى بروكسي آخر. ما أثبتته هو Fail-Closed لطلب محدد، وعودة الخدمة عند رجوع البروكسي نفسه إلى نفس نقطة الوصول. لم تُقس مدة التعافي الفعلية، ولم تُختبر أعداد كبيرة من التبويبات، ولا مواقع عامة، ولا سلوك DNS أو WebRTC أو WebSocket، ولا استهلاك الذاكرة. ولم يدخل أي حساب حقيقي أو مستخدم أو موقع خارجي في التجربة.

تجربة متابعة: التنقل أثناء الانقطاع في النافذة نفسها

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

اجتازت هذه الجولة ثلاثة فحوص من ثلاثة، وصدرت لها نتيجة نهائية مكتملة. وهي تزيد نطاق الأدلة من session.fetch إلى تنقل BrowserWindow عند إعادة استخدام النافذة القائمة، لكنها لا تثبت كل مسارات التنقل أو سلوك إنشاء نوافذ جديدة. ولم تختبر الجولة أي سياسة Auto Fallback أو تبديلًا تلقائيًا إلى بروكسي آخر؛ فالمقصود كان إعادة الاتصال بعد عودة المسار الأصلي فقط.

في التشخيص الأول لإنشاء نافذة جديدة بعد فشل التنقل، توقفت أداة الفحص قبل اكتمال التقرير، فبقي السبب غير محسوم. ثم سجلت الأدوات حدث بدء إنهاء Electron تلقائيًا بعد إغلاق آخر نافذة اختبار. كانت الأداة تحاول إنشاء نافذة جديدة بعد بدء إنهاء العملية، ما يفسر التعليق المرصود في ذلك الاختبار. هذه مشكلة في إدارة دورة حياة أداة الاختبار، وليست دليلًا على وجود عيب مطابق في محرك المتصفح الإنتاجي.

تشخيص التعليق عند إنشاء نافذة جديدة: السبب والإصلاح

عندما أُغلقت آخر نافذة داخل أداة الفحص، أطلق Electron أحداث إنهاء التطبيق تلقائيًا. أظهرت سجلات التجربة غير المصححة أن محاولة إنشاء نافذة جديدة جاءت بعد بدء الإنهاء؛ لذلك لم يكن توقف إنشاء النافذة دليلًا كافيًا على خلل في اتصال البروكسي أو في واجهة المتصفح. وباستخدام معالج لحدث window-all-closed يحافظ على حياة عملية الاختبار إلى نهاية السيناريو، أصبح بالإمكان إنشاء نافذة جديدة بعد إعادة البروكسي بشكل صحيح.

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

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

تدرّج الاختبارات اللاحقة

بعد استكمال اختبار إعادة استخدام النافذة واختبار إنشاء نوافذ جديدة، أصبحت الأولوية لفحص عدة تبويبات متزامنة وتغيير البروكسي للتاب النشط أثناء انقطاع الشبكة، ومراقبة مدة التعافي. وينبغي أن تبقى سياسة Auto Fallback موضوع اختبار منفصل بصلاحيات وتوقعات واضحة، لا أن نستنتجها من نجاح التعافي عند عودة البروكسي الأصلي.

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

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

خلاصة عملية للمطورين

اجعل لكل بروفايل سياسة شبكة صريحة، واكتب سلوك الانقطاع قبل حدوثه. سجّل الإشارات عند الطرف المستقبل، لا عند الواجهة فقط. افصل في التقارير بين ما اختُبر فعليًا وما استُنتج، وسمِّ الاختبار باسم السلوك الذي يقيسه. إذا كان Fail-Closed هو المطلوب، فاجعل الفشل واضحًا وقابلًا لإعادة المحاولة بعد عودة المسار. وإذا كان Auto Fallback مطلوبًا، فاجعله قرارًا مصرّحًا به ومسجّلًا، لا سلوكًا تلقائيًا يظهر فقط عند العطل.

تبقى هذه التجارب محددة لكنها مفيدة: ثبت فشل session.fetch أثناء انقطاع البروكسي دون انتقال مباشر مرصود، واستمرار جلسة أخرى مستقلة، وعودة الاتصال بعد رجوع البروكسي نفسه. كما نجح التنقل في النافذة القائمة، ثم نجح إنشاء نافذة جديدة في اختبار مصحح لإدارة دورة حياة Electron. لم تُختبر بعد سياسة Auto Fallback أو تبديل البروكسي للتاب النشط أو الاستقرار عبر عدة تبويبات تحت ضغط مستمر. للمزيد راجع مختبر إيجي تاج، والموقع العربي للمتصفح.

للمقارنة مع تجربة سابقة: اختبار عزل جلستين والكوكيز عبر أربع طرق اتصال.

هل تريد الاحتفاظ بالمقال أو إعادة استخدامه؟
مجتمع إيجي تاجعن المجتمع

شارك في تقييم ونقاش المقال

رأيك يضيف قيمة للمقال ويساعدنا على تحسين المحتوى والنقاش حوله.

تفاعل مع المقالاختر التفاعل المناسب، ويمكنك تغيير رأيك لاحقًا.
قيّم جودة المقاللا توجد تقييمات بعد — كن أول من يقيّم.

نقاش القراء

النقاش

جارٍ تحميل التعليقات…

بعد هذه المادة

تابع القراءة

كل مواد مختبر إيجي تاج للتجارب التقنية
من نفس القسم04
  1. 02
  2. 03
  3. 04
اختيار القراء

الأكثر قراءة

الترتيب الكامل
  1. 01
  2. 02
  3. 03
  4. 04
  5. 05
يتجدد مع النشر

أحدث المواد

  1. 01
  2. 02
  3. 03
  4. 04
  5. 05
  6. 06