Защита от перегрузки: карта

Перегрузка — это не одна проблема и не один механизм. Лимит частоты, backpressure, сброс нагрузки, предохранители, автоскейл и наблюдаемость решают разные части задачи и стоят на разных рубежах. Карта показывает, что за что отвечает, в каком порядке срабатывает и куда идти за деталями

Перегрузка редко выглядит как «сервис упал». Обычно это медленное удушение: латентность растёт, очереди копятся, воркеры заняты ожиданием, и в какой-то момент система перестаёт делать полезную работу, формально оставаясь живой. Защита от такого — не один механизм, а эшелоны: каждый рубеж отбивает свой класс избытка и передаёт дальше только то, что система реально потянет.

Эта карта — вход в серию «System design: resilience». Она показывает, кто за что отвечает и в каком порядке срабатывает, а детали каждого рубежа разбирают отдельные статьи. Технические рубежи опираются на живые стенды с замерами; финальная статья про инциденты — про процесс, и к ней приложены шаблоны, а не стенд.

Гравюра в стиле «Полдень»: разрез канала, где поток воды проходит пять последовательных шлюзов. На каждом часть потока сбрасывается вниз в терракотовые лотки, и река ступенчато сужается; то, что дошло до конца, крутит мельничное колесо и приводит в движение точный механизм. Над каналом — балка с наблюдательными приборами, под ним — массивный каменный фундамент. Эшелонированная защита: излишек отводится рано и дёшево

В статье

Как читать карту

Запрос идёт слева направо и на каждом рубеже может уйти из потока — быстро и дёшево. Внизу — фундамент (сколько мы вообще держим), сверху — контур обратной связи (видим ли мы, что происходит).

наблюдаемость: SLO и burn-rate — видно ли, что защита сработалаКрайDDoS, WAFЛимитrate limitingОчередьbackpressureСбросload sheddingИзоляцияbreaker, bulkheadфлуд отбит429 + Retry-Afterочередь конечнаизбыток сброшенбыстрый fallbackёмкость: сколько система держит на самом деле — и автоскейл под неё

Порядок не случаен: чем раньше отбит избыток, тем дешевле он обошёлся. Отклонить запрос на краю стоит доли миллисекунды; тот же запрос, дошедший до базы и там упёршийся в пул, стоит уже занятого воркера, коннекта и чужого ожидания.

Одна оговорка к схеме: это не строгий конвейер. Слева направо выстраиваются рубежи, которые смотрят на входящий поток, — край, лимит, очередь, сброс. А изоляция устроена иначе: предохранитель и переборки не стоят «последними воротами», они обхватывают конкретные вызовы и пулы и работают в момент обращения к каждой зависимости, в том числе к нескольким одновременно и на любом этапе обработки. Точнее думать о них как о втором, частично ортогональном контуре: первый ограничивает вход, второй не даёт чужому отказу растечься внутри. Ёмкость и наблюдаемость — тем более сквозные, а не ступени.

Ёмкость

Фундамент под всеми рубежами: сколько система держит на самом деле. Без этого числа лимиты назначаются наугад.

Ключевая неинтуитивность: деградация не линейна. При 80% загрузки латентность ещё терпимая, при 95% система «внезапно» встаёт — это математика очередей, а не мистика. Разбор — в теории очередей и планировании ёмкостиСкоро, а почему смотреть надо на хвост, а не на среднее, — в перцентилях и tail latencyСкоро. Узнать реальный потолок можно только измерением: нагрузочное тестирование и chaosСкоро.

Край

Первый рубеж отбивает то, что даже не должно доходить до приложения: объёмный флуд L3/L4, явное злоупотребление, ботов. Здесь работают провайдер, CDN и WAF — защита от DDoS и злоупотребленийСкоро. Рядом стоит API-шлюзСкоро: единая точка, где удобно держать грубые лимиты для всех сервисов за ним.

Лимит

Дальше решается вопрос «сколько запросов вообще впустить». Это уже прикладной поток: лимит на клиента, ключ, тариф или операцию. Здесь выбирают алгоритм (вёдра против окон), решают, ставить ли общий счётчик на все инстансы, и как отказывать честно — 429 с Retry-After, а не тихая потеря.

Rate limiting и throttling — со стенда: фиксированное окно пропускает вдвое больше лимита на стыке, а три инстанса с локальными лимитерами — втрое больше глобального.

Очередь и backpressure

Лимит защищает от избытка снаружи, но система может не успевать и в рамках лимита: замедлилась зависимость, подорожали запросы. Тогда работает следующий рубеж — ограниченная очередь и сигнал «медленнее» вверх по цепочке. Главное правило: очередь обязана быть конечной. Неограниченная очередь не защищает, а превращает отказ в бесконечно растущую латентность.

Backpressure и load sheddingготовится, с 16 сентября.

Сброс и деградация

Когда притормозить источник нельзя (пользователи не «замедляются»), остаётся сознательно отдать часть: сбросить избыток, обслужить приоритетное, ответить упрощённо. Это не поражение, а проектное решение: лучше обслужить 80% хорошо, чем 100% никак.

Здесь же живёт деградация по приоритету и fallback — и важно, что решение «без чего можно жить» продуктовое, а не техническое.

сброс нагрузкиготовится, с 16 сентября и раздел про fallback в resilience-паттернахготовится, с 14 сентября.

Изоляция

Последний рубеж внутри обработки: не дать чужому отказу стать нашим. Медленная зависимость — худший случай: она не падает, а занимает ресурсы, пока пул не кончится. Предохранитель превращает медленный отказ в быстрый, переборки не дают одному потребителю выбрать весь пул.

Resilience-паттерныготовится, с 14 сентября — со стенда: под зависшей зависимостью сервис упирается в размер пула и почти перестаёт отвечать, пока не появится circuit breaker.

Автоскейл

Медленный контур: если нагрузка выросла надолго, правильный ответ — не вечно отклонять, а добавить мощности. Важно понимать его темп: автоскейл работает десятками секунд и минутами, поэтому он не заменяет быстрые рубежи, а дополняет их — пока приедут новые поды, держат лимит и сброс.

HPA, VPA и KEDAготовится, с 13 октября, а также requests/limits и QoSготовится, с 6 октября: без честных запросов ресурсов автоскейл принимает неверные решения.

Наблюдаемость

Сквозной контур. Все рубежи выше бесполезны, если не видно, какой именно сработал и почему: отклоняем по лимиту или сбрасываем от насыщения — это разные диагнозы с разным лечением. Сигналом должно быть не «CPU высокий», а симптом для пользователя и скорость сжигания бюджета ошибок.

SLO, error budget и burn-rate алертыготовится, с 13 октября.

Когда не удержало

Ни один эшелон не даёт гарантии. Две статьи серии — про то, что происходит после:

  • Disaster Recoveryготовится, с 18 сентября — RTO/RPO, стратегия бэкапов и restore-тест, который превращает «бэкапы есть» в проверенный факт.
  • Инциденты и постмортемыготовится, с 20 сентября — процесс, без которого технические предохранители не превращаются в улучшения.

Особняком в серии стоит координация и распределённые блокировкиготовится, с 15 сентября: это не рубеж защиты от перегрузки, но соседняя задача устойчивости — как не дать двум инстансам одновременно испортить одни данные.

С чего начать

  • «Нас заваливает запросами»лимит, затем край и защита от злоупотребленийСкоро.
  • «Запросов столько же, но всё встало»ёмкостьСкоро и backpressureготовится, с 16 сентября: скорее всего подорожал запрос или замедлилась зависимость.
  • «Один сервис тормозит — падает всё»изоляцияготовится, с 14 сентября: таймауты, предохранитель, переборки.
  • «Не понимаем, что происходит под нагрузкой»SLO и burn-rateготовится, с 13 октября плюс нагрузочное тестированиеСкоро.

Соседние карты

  • Надёжность распределённых систем — шире: согласованность, транзакции, консенсус; перегрузка там один из срезов.
  • Карта обмена сообщениями — брокеры и гарантии доставки, где очереди и backpressure выглядят иначе.
  • Карта хранилищ данныхготовится, с 22 сентября — куда упирается нагрузка, дойдя до данных.

Обсуждение в Telegram

Присоединиться →

Комментарии