АрхитектураНадёжность и производительностьИнженер по надёжности сайтов (SRE)

На пике нагрузки сервис начинает заранее отклонять часть запросов, хотя CPU ещё не исчерпан. Зачем применяю...

На пике нагрузки сервис начинает заранее отклонять часть запросов, хотя CPU ещё не исчерпан. Зачем применяют такой механизм?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Это сброс нагрузки (load shedding): сервис намеренно отклоняет часть запросов до исчерпания внутренних ресурсов, чтобы сохранить приемлемую задержку и успешность для оставшихся. CPU может быть свободен, если узким местом стали база данных, внешняя зависимость, пул соединений, очередь или лимит пропускной способности.

Исторический контекст

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

Обычная стратегия «принять все запросы и обработать их позже» плохо работает для интерактивных систем. При ограниченных ресурсах полезнее быстро отказать части запросов, чем задержать или сорвать почти все.

Постановка проблемы

Свободный CPU не означает наличие свободной пропускной способности. Запрос может ждать соединение с базой, место в очереди, ответ внешнего сервиса или завершение операции, ограниченной последовательной секцией.

Если сервис продолжает принимать запросы без ограничения, очередь увеличивается. В результате нарушаются SLO по задержке, растёт число таймаутов, а зависимые компоненты получают дополнительную нагрузку. Неверная реализация также опасна: без приоритетов могут быть отброшены критичные операции, а автоматические повторы клиентов способны усилить перегрузку.

Подробное решение

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

Обычно сохраняют запросы с более высокой ценностью, например операции управления или уже начатые пользовательские транзакции, а второстепенные запросы отклоняют первыми. Клиенту следует вернуть однозначный сигнал временной перегрузки, чтобы он не повторял запрос немедленно и использовал ограниченную стратегию повторов с задержкой.

Преимущество подхода — защита хвостовой задержки, пулов ресурсов и зависимостей. Цена — намеренная потеря части трафика, поэтому критерии отказа должны соответствовать SLO и бизнес-приоритетам. Нужно также учитывать, что отклонение небезопасного для повтора запроса может привести к неполному бизнес-операционному результату; для таких операций необходимы идемпотентность или явное состояние выполнения.

Сброс нагрузки не заменяет масштабирование и устранение узкого места. Он стабилизирует систему во время пика, но постоянное превышение спросом доступной ёмкости требует изменения архитектуры, оптимизации зависимости или увеличения ресурсов.

Ситуация из практики

Сервис оформления заказа использует CPU лишь на 45%, но его пул соединений с базой заполнен. Все новые запросы принимаются в очередь, из-за чего p99 задержки превышает SLO, а клиенты начинают повторять оформление заказа.

Рассматривались три варианта. Увеличение пула соединений могло повысить пропускную способность, но создавало риск перегрузить базу. Увеличение числа экземпляров почти не помогало, поскольку общий лимит базы оставался узким местом. Безусловный отказ всех новых запросов хорошо защищал базу, но ухудшал пользовательский опыт и не учитывал приоритеты.

Выбрали ограничение допуска на уровне очереди: уже принятые заказы завершались, второстепенные операции отклонялись раньше, а новые заказы получали временный отказ с контролируемым повтором. Это сохранило запас базы, уменьшило p99 и позволило критичным операциям укладываться в SLO. При этом команда отдельно оптимизировала запросы к базе, поскольку сам механизм отказа не устранял первопричину.

Что кандидаты часто упускают

  1. Почему нельзя ориентироваться только на загрузку CPU при принятии решения об отказе?

CPU отражает лишь один ресурс и может оставаться свободным при насыщении другого ограничителя. Пропускную способность часто определяют пул соединений, лимит запросов внешнего сервиса, память, дисковое ожидание, блокировки или последовательная секция обработки. Поэтому решение должно учитывать ресурс, который фактически ограничивает прохождение запроса, а не универсальный процент загрузки.

  1. Чем сброс нагрузки отличается от таймаута?

Сброс нагрузки отказывает до начала дорогой обработки или до постановки запроса в чрезмерно длинную очередь. Таймаут обычно обнаруживает проблему после ожидания и уже тратит часть ресурсов на обречённый запрос. Поэтому ранний отказ лучше защищает задержку и зависимые системы, хотя требует корректной классификации запросов и понятного контракта для клиентов.

  1. Почему load shedding может ухудшить ситуацию, если клиенты автоматически повторяют запросы?

Если каждый отказ вызывает немедленный повтор, фактическое число попыток растёт, а система получает дополнительный поток именно в момент перегрузки. Это может превратить защитный механизм в источник повторной нагрузки. Нужны ограничение числа попыток, экспоненциальная задержка с джиттером, учёт дедлайна и различение временного отказа от окончательного; для изменения состояния также требуется идемпотентность.