هذا المقال يتطلب مستوى: متوسط. تحتاج تكون تعاملت قبل كده مع خدمة بتنادي خدمة تانية (API داخلي أو خارجي)، وتعرف يعني إيه timeout وthread pool. لو لسه مبتدئ، فيه مثال بسيط في الأول هيوصّلك الفكرة قبل الشرح التقني.
قاطع الدائرة Circuit Breaker: امنع فشل خدمة واحدة من إسقاط نظامك كله
لو خدمة واحدة بطيئة قدرت توقّع النظام بالكامل، اللي قدامك هنا بيمنع ده. هتتعلّم تعزل العطل بدل ما تسيبه ينتشر، وترجّع خطأ فوري في أقل من مللي ثانية بدل ما تستنى timeout تقيل.
المشكلة باختصار
تخيّل خدمة الدفع عندك بطؤت فجأة من 200 مللي ثانية لـ 8 ثواني. كل طلب دلوقتي بيحجز thread وهو مستني الرد. الـ thread pool عندك سعته 200 thread. في أقل من نص دقيقة كل الـ threads اتحجزت وهي بتستنى الدفع. النتيجة: مش خدمة الدفع بس اللي وقعت، الموقع كله وقف — حتى الصفحات اللي مالهاش علاقة بالدفع. ده اسمه الانهيار المتسلسل (cascading failure). عطل في مكان واحد بيسحب معاه النظام كله.
الطريقة الشائعة إنك تعتمد على الـ timeout بس. المشكلة إن الـ timeout بيفشل بعد انتظار. لو الـ timeout 8 ثواني، يبقى كل طلب بيضيّع 8 ثواني قبل ما يستسلم، وخلال الوقت ده الـ threads بتتراكم. الافتراض هنا إن عندك dependency (خدمة تعتمد عليها) وارد إنها تبطأ أو تفشل.
الفكرة الأساسية: زي القاطع الكهربائي في بيتك
في لوحة الكهرباء في البيت فيه قاطع. لما جهاز يعمل شورت، القاطع بيفصل الكهرباء عن الخط ده على طول. ليه؟ علشان يحمي باقي البيت من إن السلك يسخن ويولّع. القاطع مبيصلّحش الجهاز، هو بس بيعزل المشكلة بسرعة قبل ما تكبر.
قاطع الدائرة في البرمجيات بيعمل نفس الحاجة بالظبط. بيراقب الاستدعاءات لخدمة معيّنة. لو لاحظ إنها بتفشل كتير، بيقطع الاستدعاءات عنها مؤقتًا. أي طلب جديد بيرجع بخطأ فوري بدل ما يحاول ويستنى ويفشل. كده بتحمي الـ threads والموارد بتاعتك من إنها تتحرق في انتظار خدمة عارف إنها تعبانة.
إزاي بيشتغل علميًا: ثلاث حالات
قاطع الدائرة عبارة عن آلة حالات (state machine) بسيطة بثلاث حالات. الصورة دي بتلخّص الانتقالات بينها:
- CLOSED (مغلق): الوضع الطبيعي. الطلبات بتعدّي للخدمة عادي. القاطع بيعدّ نسبة الفشل في الخلفية.
- OPEN (مفتوح): لما الفشل يعدّي الحد (مثلاً 5 حالات متتالية أو 50% فشل في نافذة زمنية)، القاطع بيتفتح. كل طلب جديد بيترفض فورًا بدون ما يلمس الخدمة، في أقل من مللي ثانية. ده الـ fail fast.
- HALF-OPEN (نصف مفتوح): بعد فترة تهدئة (مثلاً 30 ثانية)، القاطع بيسمح بطلب اختبار واحد يعدّي. لو نجح، معناه الخدمة رجعت، فيرجع CLOSED. لو فشل، يرجع OPEN تاني ويستنى فترة كمان.
مثال تنفيذي: قاطع دائرة في Python من الصفر
ده قاطع دائرة مبسّط شغّال، علشان تشوف المنطق واضح. في الإنتاج استخدم مكتبة جاهزة (هتلاقيها تحت)، بس الكود ده بيوريك اللي بيحصل جوّه.