Суть Circuit Breaker аналогична электрическому автомату: при обнаружении множества ошибок во внешних вызовах (например, к платежному шлюзу или сервису рекомендаций) «цепь» разрывается. Последующие запросы не пытаются выполниться, а сразу получают отлуп (fallback), например, стандартные рекомендации или кешированные данные. Это дает сбойному сервису время на восстановление и предотвращает исчерпание критических ресурсов (потоков, соединений) в вызывающем сервисе.
Паттерн имеет три четких состояния: ЗАКРЫТО (CLOSED), ОТКРЫТО (OPEN), ПОЛУОТКРЫТО (HALF-OPEN). В состоянии CLOSED запросы проходят как обычно. При превышении порога ошибок (например, 50% за последние 60 секунд) автомат переходит в состояние OPEN. Все новые запросы мгновенно отклоняются. Через заданный таймаут (timeout) автомат переходит в состояние HALF-OPEN, пропуская пробный запрос. Если он успешен — цепь снова CLOSED, если нет — возвращается в OPEN.
Кейс: крупный маркетплейс столкнулся с проблемой в день больших распродажд (Black Friday). Сервис формирования персональных рекомендаций, к которому обращался каждый запрос к каталогу, не выдерживал пика и начинал отвечать с таймаутами. Это вызывало цепную реакцию: потоки в веб-сервисах каталога блокировались в ожидании ответа, их число росло, исчерпывая пул соединений, что в итоге приводило к полной недоступности страниц товаров.
Решение было внедрить Circuit Breaker на стороне сервиса каталога для всех вызовов к сервису рекомендаций. Использовалась библиотека Resilience4j для Java. Конфигурация была следующей: порог срабатывания — 50% ошибок за скользящее окно в 100 запросов, время в состоянии OPEN — 10 секунд, в HALF-OPEN — разрешен 1 пробный запрос.
Результат был впечатляющим. В момент следующего пика, когда сервис рекомендаций начал «тонуть», автомат сработал за 2 секунды. Запросы к каталогу перестали зависать и вместо «замороженных» рекомендаций начали возвращать топ популярных товаров из локального кеша (реализация fallback). Общая доступность каталога сохранилась на уровне 99.95%, несмотря на частичную деградацию функциональности. Сервис рекомендаций, изолированный от лавинообразного трафика, восстановился через 45 секунд, после чего автомат вернулся в нормальное состояние.
Важные детали реализации для highload:
- **Разделение автоматов**: Не используйте один автомат на все вызовы. Разделите их по типу операции или endpoint (например, /recommendations/personal и /recommendations/top). Это обеспечит более точную изоляцию.
- **Метрики и мониторинг**: Состояние каждого Circuit Breaker (переключения, количество отказов, latency) должно быть ключевой метрикой в Prometheus/Grafana. Это позволяет видеть проблемы в реальном времени.
- **Асинхронность**: В highload-системах вызовы через Circuit Breaker должны быть неблокирующими (реактивные паттерны, CompletableFuture, корутины).
- **Умный fallback**: Стратегия отступления должна быть продумана. Это может быть кеш, заглушка, запрос к альтернативному, менее точному сервису или даже упрощенная локальная логика.
Комментарии (7)