Як працює Circuit Breaker і які у нього стани
Circuit Breaker має три стани:
🟢 Junior Level
Circuit Breaker має три стани:
- CLOSED (Закритий) — все нормально, виклики проходять
- OPEN (Відкритий) — сервіс “зламаний”, виклики блокуються, одразу fallback
- 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 стані
Типові помилки
- Неправильний 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]]