Питання 6 · Розділ 17

Як працює Circuit Breaker і які у нього стани

Circuit Breaker має три стани:

Мовні версії: English Russian Ukrainian

🟢 Junior Level

Circuit Breaker має три стани:

  1. CLOSED (Закритий) — все нормально, виклики проходять
  2. OPEN (Відкритий) — сервіс “зламаний”, виклики блокуються, одразу fallback
  3. HALF-OPEN (Напіввідкритий) — пробний виклик для перевірки
Початок: CLOSED (виклики проходять)
         ↓ занадто багато помилок
        OPEN (блокуємо виклики 10 секунд)
         ↓ час вийшов
        HALF-OPEN (один пробний виклик)
         ↓ успіх → CLOSED
         ↓ помилка → OPEN (знову чекати)

🟡 Middle Level

Деталі переходів

CLOSED → OPEN:

failureRate > threshold (наприклад 50%)
АБО slowCallRate > threshold (наприклад > 50% повільних)

OPEN → HALF-OPEN:

waitDurationInOpenState elapsed (наприклад 10 секунд)

HALF-OPEN → CLOSED:

permittedNumberOfCallsInHalfOpenState успішних викликів
(наприклад 3 успішних виклики)

HALF-OPEN → OPEN:

Будь-яка помилка в HALF-OPEN стані

Типові помилки

  1. Неправильний sliding window:
    slidingWindowSize = 5 → занадто мало
    Одна помилка = 20% failure rate
    Краще: 10-100 викликів
    

🔴 Senior Level

Internal Implementation

Metrics tracking:

// Ring buffer для зберігання результатів викликів
class SlidingWindow {
    private final CircularArray measurements;

    void record(CallResult result) {
        measurements.add(result);
        // Якщо minCalls ніколи не набрано — breaker НЕ відкриється, навіть якщо УСІ виклики
        // FAILED. Це важливо: при малому трафіку circuit breaker може не спрацювати.
        if (measurements.size() >= minCalls) {
            double failureRate = calculateFailureRate();
            if (failureRate > threshold) {
                stateTransition(CLOSED, OPEN);
            }
        }
    }
}

Production Experience

Monitoring:

// Метрики для моніторингу
CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
metrics.getFailureRate();       // % помилок
metrics.getNumberOfBufferedCalls();
metrics.getNumberOfFailedCalls();
metrics.getState();             // CLOSED/OPEN/HALF-OPEN

Best Practices

// Ці патерни НЕ альтернативи, а комплементарні: // Retry + Timeout + CircuitBreaker використовуються разом.

✅ minimumNumberOfCalls = 10+ (статистично значуща вибірка)
✅ failureRateThreshold = 50% (компроміс: не відкриваємо від однієї помилки, але і не чекаємо поки все впаде)
✅ waitDurationInOpenState = 10-60s (достатньо щоб залежний сервіс перезапустився, але не занадто довго)
✅ permittedCallsInHalfOpen = 3-5

❌ Занадто малий sliding window
❌ Занадто короткий wait duration
❌ Без моніторингу метрик

🎯 Шпаргалка для співбесіди

Обов’язково знати:

  • Три стани: CLOSED, OPEN, HALF-OPEN з чіткими правилами переходів
  • CLOSED→OPEN: failure rate > threshold (50%), OPEN→HALF-OPEN: wait duration elapsed
  • HALF-OPEN→CLOSED: N успішних викликів, HALF-OPEN→OPEN: будь-яка помилка
  • Sliding window (count-based або time-based) для відстеження метрик
  • minimumNumberOfCalls = 10+ для статистично значущої вибірки
  • При малому трафіку circuit breaker може не спрацювати (не набрано minCalls)
  • Ring buffer для зберігання результатів викликів

Часті уточнюючі питання:

  • Що таке permittedNumberOfCallsInHalfOpen? Скільки пробних викликів зробити в HALF-OPEN — якщо усі успішні, повернутись в CLOSED.
  • Чому minimumNumberOfCalls важливий? Без нього breaker відкриється від 1-2 помилок при малому трафіку.
  • Як моніторити CB? Метрики: failure rate, buffered calls, failed calls, поточний стан.
  • Count-based vs time-based window? Count-based = останні N викликів, time-based = виклики за T секунд.

Червоні прапорці (НЕ говорити):

  • “Sliding window = 5 достатньо” — ні, одна помилка = 20% failure rate
  • “Wait duration = 1 секунда” — сервіс не встигне перезапуститися
  • “CB працює без метрик” — неможливо налаштувати без моніторингу
  • “HALF-OPEN пропускає весь трафік” — ні, тільки permittedNumberOfCalls

Пов’язані теми:

  • [[5. Що таке патерн Circuit Breaker]]
  • [[17. Як забезпечити відмовостійкість мікросервісів]]
  • [[19. Що таке патерн Retry і як його правильно використовувати]]
  • [[21. Як моніторити розподілену систему мікросервісів]]
  • [[20. Що таке exponential backoff]]