Circuit Breaker на собеседовании системного аналитика
Карьерник — Duolingo для аналитиков: 10 минут в день тренируй SQL, Python, A/B, статистику, метрики и ещё 3 темы собеса. 1500+ вопросов в Telegram-боте. Бесплатно.
Содержание:
Зачем спрашивают на собесе SA
Resilience patterns — must-know для микросервисной архитектуры. На собесе SA: «как работает circuit breaker», «отличие от retry», «зачем bulkhead».
Идея circuit breaker
Сервис A зависит от сервиса B. B падает / медленный — A продолжает делать запросы и тоже встаёт (cascade failure).
Circuit breaker — автоматический «выключатель» вызовов B, если он плохо работает. После cooldown — проверка, если работает, возвращаем normal flow.
Состояния: closed / open / half-open
Closed. Нормальное состояние. Запросы проходят. Failures считаются.
Open. После N failures за период — переключение в open. Запросы немедленно fail без обращения к downstream. Защита downstream от добивания + быстрая ошибка для caller.
Half-open. После cooldown timer — пропускаем 1-N тестовых запросов. Если успешные → closed. Если fail → open снова.
request fails
closed ──────────────→ open
↑ │
│ test passes │ cooldown timer
│ ↓
└────── half-open ←──┘
(тестовый запрос)Retries и timeouts
Circuit breaker — не единственный pattern. Часто используется вместе с:
Timeout. Не ждать ответа дольше N секунд. Без timeout — просто зависание.
Retry с exponential backoff. Повторить через 1s, 2s, 4s, 8s. Не сразу — может усугубить нагрузку.
Retry only for idempotent. GET, PUT — да. POST — нет (может создать дубль).
Jitter. Добавить randomness к backoff — иначе все клиенты retry в один момент (thundering herd).
Bulkhead pattern
Изолировать ресурсы между вызовами разных downstream'ов.
Без bulkhead. Один thread pool на все вызовы. Один медленный downstream забивает pool — остальные стоят.
С bulkhead. Отдельный thread pool / connection pool для каждого downstream. Деградация одного не убивает остальные.
Service A:
├─ Pool for service B (10 threads)
├─ Pool for service C (10 threads)
└─ Pool for service D (10 threads)Если B встал — A продолжает обслуживать запросы к C и D.
Реализация
Hystrix (Netflix, deprecated). Стандарт раньше.
Resilience4j (Java). Современный.
Polly (.NET). Resilience policies.
istio / Envoy — на уровне sidecar.
Custom. Простой circuit breaker — пара десятков строк Python / Go.
class CircuitBreaker:
def __init__(self, threshold=5, timeout=30):
self.failures = 0
self.threshold = threshold
self.last_failure = None
self.timeout = timeout
def call(self, fn):
if self.is_open():
raise CircuitOpenError
try:
result = fn()
self.failures = 0
return result
except Exception:
self.failures += 1
self.last_failure = time.time()
raiseЧастые ошибки
Высокий threshold. «10 failures за 5 минут» — слишком terpимо, downstream добивается. Обычно 3-5 за минуту.
Slow timeout. 60-секундный timeout на user-facing — катастрофа. 500ms-3s стандарт.
Ретрай non-idempotent. Дубли, money lost.
Без jitter. Thundering herd при cooldown.
Полагаться только на CB. Comprehensive resilience — timeouts + retries + CB + bulkhead.
Связанные темы
- API Gateway и BFF для SA
- Монолит vs микросервисы для SA
- 2PC vs Saga для SA
- SLA SLO SLI для SA
- Подготовка к собесу системного аналитика
FAQ
Где SA участвует в circuit breaker?
В нефункциональных требованиях: «вызовы к Service B должны иметь timeout 2s, retry 3, circuit breaker threshold 5».
Это официальная информация?
Нет. Статья основана на работах Martin Fowler, Michael Nygard «Release It!», документации Istio.
Тренируйте системный анализ — откройте тренажёр с 1500+ вопросами для собесов.