Система надёжна, если продолжает работать, когда что-то ломается. А ломается всегда: диски, сети, зависимости, деплои.
SLI, SLO, SLA
- SLI (индикатор): измеряемая метрика. Доля успешных запросов, p99 задержки.
- SLO (цель): целевое значение SLI. «99,9% запросов успешны за 30 дней», «p99 < 300 мс».
- SLA (соглашение): обещание клиенту с последствиями (компенсации). SLA обычно мягче внутреннего SLO.
Error budget: при SLO 99,9% можно «потратить» 0,1% на ошибки. За 30 дней это около 43 минут простоя. 99,99% это уже около 4,3 минуты в месяц. Если бюджет исчерпан, замедляют релизы и чинят надёжность.
Перцентили, а не среднее
Средняя задержка прячет хвост. p99 = 800 мс значит, что 1% запросов медленнее 800 мс. Если страница делает 100 запросов к бэкенду, почти каждый пользователь попадёт в этот хвост.
Таймауты, ретраи, jitter
- Каждый сетевой вызов должен иметь таймаут. Без него зависшая зависимость съедает все потоки или соединения.
- Ретраи только для идемпотентных операций или с ключом идемпотентности.
- Экспоненциальная задержка с jitter: 100 мс, 200, 400 плюс случайный разброс, чтобы клиенты не повторяли синхронно.
- Ограничивайте число ретраев и общий бюджет. Ретраи на каждом из 3 уровней по 3 раза дают до 27 запросов к нижнему сервису: retry storm.
Circuit breaker
Если зависимость часто падает, «размыкаем цепь»: перестаём её вызывать на время и сразу отдаём ошибку или фолбэк. Состояния: closed (работаем), open (не вызываем), half-open (пробуем несколько запросов). Защищает упавший сервис от добивания и наш сервис от ожидания.
Bulkhead и деградация
- Bulkhead: отдельные пулы ресурсов для разных зависимостей, чтобы медленная не съела всё.
- Graceful degradation: при отказе рекомендаций показываем популярное, а не ошибку страницы.
Rate limiting и load shedding
Ограничение частоты защищает от злоупотреблений и перегрузки. Алгоритмы: token bucket (разрешает всплески), leaky bucket (ровный поток), fixed window (просто, но всплеск на границе окон), sliding window. При перегрузке сервис сбрасывает часть запросов (load shedding) и отвечает 429 или 503, чтобы обслужить остальные.
Избыточность и отказоустойчивость
- Несколько экземпляров каждого сервиса в разных зонах доступности (дата-центрах).
- Реплики БД с автоматическим failover (Patroni для PostgreSQL).
- Health checks: liveness (процесс жив) и readiness (готов принимать трафик).
- Бэкапы, которые регулярно проверяют восстановлением.
RPO: сколько данных можно потерять (время с последней копии). RTO: за сколько восстановиться.
Наблюдаемость: метрики, логи, трейсы
- Метрики (Prometheus, VictoriaMetrics + Grafana): числа во времени. Методы RED для сервисов (Rate, Errors, Duration) и USE для ресурсов (Utilization, Saturation, Errors).
- Логи (Loki, ELK): структурированные события в JSON с request id.
- Трейсы (OpenTelemetry, Jaeger): путь одного запроса через сервисы, видно, где потерялись миллисекунды.
Алерты ставят на симптомы, которые чувствует пользователь (рост ошибок, задержки, сжигание error budget), а не на каждую метрику CPU.
Частые ошибки
- Ретраи без таймаутов и без jitter.
- Ретраи неидемпотентного POST без ключа идемпотентности.
- Смотреть только на среднюю задержку.
- Обещать 99,999% без понимания, что это около 26 секунд простоя в месяц.
Что спросят на собесе
- Чем SLA отличается от SLO и SLI.
- Как работает circuit breaker.
- Как правильно делать ретраи.
- Какие алгоритмы rate limiting знаете.
- Как понять, почему запрос стал медленным в системе из 20 сервисов.