المستوى: متوسط
لو الـ checkout بتاع موقعك فجأة بيرد في 8 ثواني بدل 200 مللي ثانية، والسبب إن خدمة واحدة من 6 خدمات داخلية بطّأت أو وقفت ترد، فأنت بتدفع ثمن مشكلة معروفة اسمها cascading failure. خدمة واحدة بتفشل بهدوء بقت بتقتل التطبيق كله. الحل اسمه Circuit Breaker، وهو من أهم 5 patterns في الأنظمة الموزعة الحديثة.
Circuit Breaker: المنطق وراء الاسم
قبل أي شرح علمي، خد المثال البسيط ده. في البيت عندك علبة كهرباء فيها قواطع. لو حصل short circuit في غسالة الأطباق، القاطع المخصوص ليها بيفصل تلقائياً. النتيجة: بقية البيت بيشتغل عادي، وما اتحرقش أي سلك. الفكرة بسيطة وقوية في نفس الوقت: افصل الجزء العاطل قبل ما يحرق التطبيق كله.
في الـ microservices نفس المنطق بالظبط. لو خدمة الـ payments بتاخد 10 ثواني بدل 100 مللي ثانية، الكود اللي بيندهها بيستنى. لو 1000 request في الثانية بيندهوها، فيه 1000 thread محجوز بيستنى نفس الخدمة المعطلة. الـ thread pool بيخلص في أقل من دقيقة. السيرفر بيقع. التطبيق كله بقى رهينة خدمة واحدة.
المشكلة باختصار
تخيّل تطبيق بيتكلم مع 6 خدمات: auth، payments، shipping، inventory، notifications، analytics. لو أي واحدة منهم بطّأت، اللي بيحصل فعلاً:
- الـ HTTP client بيستنى لحد timeout الافتراضي = 30 ثانية
- الـ thread اللي بيستنى محجوز ومش بيقدر يخدم requests تانية
- الـ requests الجديدة بتتراكم في الـ queue
- بعد دقيقة الذاكرة بتمتلئ والسيرفر بيقع
ركّز هنا: المشكلة مش الخدمة اللي بطّأت. المشكلة إن تطبيقك مش عارف يقول "ما تكلّمنيش عنها دلوقتي". Circuit Breaker بيعمل ده بالظبط، وبيخلي الفشل محدود في feature واحدة بدل ما يبقى outage كامل.
إزاي بيشتغل: الحالات الثلاث
التعريف العلمي الدقيق: Circuit Breaker هو state machine بثلاث حالات (Closed, Open, Half-Open) بيقفل المسار للخدمة بعد عدد محدد من الأخطاء، وبيختبر التعافي بشكل تدريجي بدل ما يفتح فجأة على كل الـ traffic.
- Closed (الافتراضي): الـ requests بتعدّي عادي للخدمة. كل request فاشل بيزوّد counter داخلي. لو الـ counter وصل لحد معين (مثلاً 5 أخطاء متتالية)، الحالة بتتحول لـ Open.
- Open: الـ requests بترجع تلقائياً بـ exception فوراً، بدون ما توصل للخدمة. ده بيوفّر threads ووقت ومكسب فوري على tail latency. بنفضل في الحالة دي لمدة محددة (مثلاً 30 ثانية).
- Half-Open: بعد مدة الـ Open، بنسمح بـ request واحد بس يعدّي كاختبار. لو نجح، نرجع Closed. لو فشل، نرجع Open ونعيد العد.
الفايدة من Half-Open مهمة: ما بنخبطش الخدمة المعطلة فجأة بـ 1000 request مرة واحدة بعد التعافي. بنختبر بـ request واحد، وبعدين نفتح المسار تدريجياً.