Система не обязана либо работать, либо лежать
У интернет-магазина сломался сервис рекомендаций.
Что должен увидеть пользователь?
Вариант А:
500 Internal Server Error
Вариант Б:
интернет-магазин без рекомендаций.
Почему-то распределённые системы регулярно выбирают вариант А. Одна необязательная зависимость не ответила — и ошибка отправилась вверх по цепочке, пока не уронила весь пользовательский сценарий.
Но не все функции продукта одинаково критичны.
Если второстепенный компонент недоступен, система может продолжить выполнять основную задачу в degraded mode — режиме ограниченной функциональности.
Например:
— нет рекомендаций — показываем популярные товары;
— нет актуальных остатков — используем последние известные данные с предупреждением, если бизнес допускает такой риск;
— не работает сервис уведомлений — сохраняем сообщения в очередь и отправляем позже;
— недоступна аналитика — не блокируем действия пользователя;
— не отвечает внешний партнёр — принимаем операцию и завершаем асинхронно, если это разрешено бизнес-процессом.
Технически здесь понадобятся таймауты, circuit breaker, очереди, кэш и fallback-сценарии.
Но сначала нужно ответить на продуктовый вопрос:
что действительно должно продолжать работать?
Для условного интернет-магазина приоритеты могут выглядеть так:
Tier 1 — авторизация, оформление заказа, платёж.
Tier 2 — каталог и поиск.
Tier 3 — рекомендации, отзывы и персонализация.
Это не универсальная классификация. В другом продукте поиск может быть главным сценарием, а авторизация вообще не требоваться для просмотра каталога.
Поэтому graceful degradation нельзя спроектировать силами backend-команды в вакууме. Нужна заранее согласованная иерархия функций:
— что нельзя потерять ни при каких условиях;
— что может работать с ограничениями;
— что можно временно отключить;
— где допустимы устаревшие данные;
— о каких ограничениях нужно сообщить пользователю.
Хорошая отказоустойчивость не означает «никогда не ломаться».
Она означает заранее понимать, что должно продолжить работать, когда что-то сломалось.
И degraded mode нужно проверять под реальными отказами: отключать зависимости, добавлять задержки, возвращать ошибки, останавливать обработчики очередей.
Иначе он существует только на архитектурной диаграмме. А диаграммы, как известно, падают заметно реже продакшена.