Отказоустойчивость: резервирование, деградация, circuit breaker
Отказы неизбежны — вопрос не «если», а «когда»; задача инженера в том, чтобы система их пережила.
Отказоустойчивость (fault tolerance) — способность системы продолжать работу (возможно, с ухудшением) при отказе отдельных компонентов.
На масштабе тысяч серверов что-то ломается постоянно: диски, сеть, целые ЦОД. Нельзя сделать так, чтобы не падало; можно сделать так, чтобы падение одного узла не роняло систему.
Убрать единую точку отказа (SPOF)
Single Point of Failure — компонент, отказ которого роняет всю систему. Главный приём — резервирование (redundancy): дублировать критичные компоненты, чтобы при падении одного работу подхватил другой.
| Компонент | Как убрать SPOF |
| Сервер приложения | несколько инстансов за балансировщиком |
| Балансировщик | пара active-passive с плавающим IP |
| База данных | реплики + автоматический failover |
| Целый ЦОД | мультирегиональное развёртывание |
Graceful degradation
Когда часть системы сломалась, лучше отдать урезанный результат, чем ошибку. Это плавная деградация. Упал сервис рекомендаций — покажем ленту без персонализации, в общем порядке. Недоступны отзывы — отрисуем карточку товара без них. Пользователь видит чуть меньше, но сайт работает.
Таймауты и ретраи
Вызов внешнего сервиса без таймаута — мина: если он завис, ваш поток ждёт вечно, потоки кончаются, сервис встаёт. Всегда ставьте таймаут. Ретраи помогают пережить разовый сбой, но усиливают перегрузку, если сервис и так лежит. Поэтому ретраи делают с экспоненциальной задержкой и jitter (случайным разбросом), а не подряд.
Наивно: повтор сразу, ещё раз сразу… → добиваем упавший сервис
Правильно: ждать 1с, потом 2с, потом 4с (+случайный jitter), и предел попыток
Circuit breaker (предохранитель)
Circuit breaker — обёртка над вызовом сервиса, которая при серии ошибок «размыкает цепь» и перестаёт его дёргать, мгновенно отдавая отказ или запасной ответ.
Логика как у электрического предохранителя: если сервис стабильно падает, бессмысленно слать ему запросы и ждать таймаут на каждом. Breaker это замечает и временно «отрезает» вызовы, давая сервису восстановиться и не тратя ваши ресурсы на безнадёжные попытки.
| Состояние | Поведение |
| Closed (замкнут) | запросы идут как обычно; считаем ошибки |
| Open (разомкнут) | порог ошибок превышен — запросы не шлём, сразу отказ/фолбэк |
| Half-open | спустя время пробуем один запрос: ок → closed, нет → снова open |
Circuit breaker предотвращает каскадные отказы — когда падение одного сервиса по цепочке тянет за собой все остальные, ждущие его ответа.
Итог
- Отказы неизбежны: убирайте SPOF резервированием критичных компонентов.
- Graceful degradation отдаёт урезанный ответ вместо ошибки; таймауты обязательны, ретраи — с экспоненциальной задержкой.
- Circuit breaker отрезает падающий сервис и предотвращает каскадные отказы.