Rate limiting в nginx: где сервер ломается без лимитов
Всплеск запросов редко приходит равномерно. Чаще это один клиент, сорвавшийся скрипт обхода каталога или внешний робот, который открывает сотни параллельных соединений и не отпускает их до истечения времени ожидания. Сервер при этом формально жив: процесс запущен, порт слушает, но обработчики заняты одним источником.
Пул обработчиков — общий и конечный ресурс. Когда все доступные обработчики ждут ответа от базы или внешнего сервиса на тяжёлых запросах, новые обращения встают в очередь на приём. Очередь растёт быстрее, чем её успевают разбирать, а отклик для остальных клиентов уезжает с долей секунды до десятков секунд.
Дальше включается каскад: пользователи не дожидаются и уходят, а автоматические повторные попытки добавляют нагрузку. В логах это выглядит одинаково — обрыв соединений под пиком при неизменном коде, рост доли ошибок и предупреждений о нехватке свободных обработчиков. Причина не в железе, а в исчерпании пула обработчиков и накопленных ожиданиях.
Внешний экран перед сервером эту картину не различает: он режет всех подряд, включая уведомления платёжной системы и обход поисковых роботов. Rate limiting nginx работает ближе к приложению — считает частоту по ключу (адрес, сессия, токен доступа, путь) и отдаёт лишним корректный ответ вместо места в очереди. Перегрузка веб-сервера перестаёт быть общим событием: ограничение получает конкретный источник, остальные обслуживаются как обычно. Разбираем, как настраивается такая защита от всплеска запросов и где проходит граница между ней и блокировкой своих же пользователей.
Что даёт ограничение частоты запросов на входе
Время отклика перестаёт расти под пиком
Правило на входном прокси (nginx) работает раньше приложения: лишний поток получает короткий отказ и не занимает рабочие процессы. Очередь не накапливается, поэтому стабильное время отклика держится и на пике — в час рассылки или старта акции вместо роста в разы. Пороги выставляются по нагрузочному профилю, снятому на реальном трафике, а не после аварии.
Отсекаются перебор паролей и массовый парсинг каталога
Отдельное правило на форму входа считает не только частоту, но и долю неудачных попыток с одного адреса — серия из сотен ошибок не превращается в подбор. Для каталога порог мягче: отсечение парсеров оставляет людям полный доступ, а скрипту с одного адреса — лишь часть страниц за минуту. Поисковые роботы идут по отдельному списку и работают без ограничений.
Отказ одного клиента не роняет остальных
Изоляция клиента нужна там, где за одним адресом стоит офис или выгрузка партнёра: без неё один всплеск занимает все рабочие процессы и роняет сервис для всех. С разделением по адресу, ключу доступа и сессии упирается только нарушитель, остальные продолжают работать. Так уходит целый класс отказов — не «сервер упал», а «конкретный источник исчерпал свою квоту».
Rate limiting в nginx: уровни защиты и их ограничения
Лимиты размещают на нескольких уровнях, и каждый закрывает свой класс перегрузки. Чем ближе счётчик к клиенту, тем дешевле отказ: запрос, срезанный на внешнем прокси, не доходит ни до приложения, ни до базы.
Где ставить лимит
| Уровень | Когда подходит | Ограничения |
|---|---|---|
| Внешний прокси перед входом | Массовые всплески, сканеры, перебор по формам входа | Виден только адрес клиента: за офисной сетью квота делится на всех, распределённый поток её обходит |
| Входной nginx: лимит по частоте и по одновременным соединениям | Рабочий вариант для сайта и API | Зона и ключ учёта должны быть согласованы; на нескольких узлах без общего хранилища счётчики независимы, суммарный лимит размывается |
| Приложение или шлюз | Лимиты по аккаунту, токену, роли, отдельному маршруту | Считается после разбора запроса — дороже; правила расходятся с конфигом балансировщика |
Ключ учёта — главный выбор: адрес клиента, адрес с учётом реального источника за прокси, сессия или токен. Чем точнее ключ, тем меньше ложных срабатываний на общих адресах.
Чего лимиты не решают
Лимит частоты — это про честную нагрузку и грубые всплески, а не про защиту целиком. Он не остановит медленный перебор малой интенсивностью с множества адресов и не спасёт от дорогого запроса, который укладывается в квоту, но нагружает базу. Бота от клиента он тоже не отличит, если ключ — только адрес.
Поэтому лимиты работают в связке с кэшированием, таймаутами, ограничением размера тела запроса и разбором логов: каждое закрывает свой участок, и по отдельности ни одно из них не даёт устойчивости.
Этапы внедрения ограничений: от аудита до регламентов
Начинаем с аудита входящего трафика: разбираем логи обратного прокси, находим маршруты и источники с основным объёмом, пиковые интервалы и долю служебных запросов. Из этого собираем профиль нагрузки — темп, который сервис держит с запасом, и точки, где начинается деградация.
- Аудит входящего трафика — логи, маршруты, источники, пиковые интервалы.
- Профиль нагрузки — какой темп сервис переваривает, а какой ведёт к росту времени ответа.
- Схема зон и порогов — где ставить лимит: на входе в кластер, на отдельном сервисе или на дорогом маршруте, с разными порогами для авторизованных и анонимных клиентов.
- Настройка правил — сами лимиты, коды ответа, заголовки с остатком квоты, поведение при превышении.
- Проверка на тестовом контуре — правила прогоняем на копии окружения, чтобы увидеть, кого именно ограничивает лимит.
- Нагрузочный прогон и передача регламентов — держим пик, сверяем метрики с планом, отдаём команде документ с порогами и порядком их пересмотра.
Как проходит проверка под пиком
Прогон повторяет профиль нагрузки из аудита, включая короткие всплески от одного источника. Проверяем, что лимит срабатывает раньше, чем растёт время ответа у остальных, и что легитимный трафик под порог не попадает — иначе ограничение бьёт по своим.
Что нужно с вашей стороны
Доступ к логам и метрикам сервиса, окно для проверки на копии окружения и контакт дежурного, который подтвердит пороги. Остальное — наша работа: правила, прогон, регламент и разбор результатов.
Что остаётся у вас: конфигурации, схемы зон и регламенты
Мы передаём не «настроенный сервер», а рабочий комплект: конфигурации ограничения частоты запросов в nginx, схему зон и порогов, перечень доверенных адресов, инструкцию дежурному и регламент реакции на инцидент. Всё лежит в репозитории заказчика, изменения проходят ревью и раскатываются по обычному процессу поставки.
Состав пакета документов
- Конфигурации с комментариями: по какому ключу считается лимит (адрес, токен, cookie) и какие зоны объявлены.
- Схема зон и порогов — таблица «зона → лимит → всплеск → код ответа», чтобы значения менялись осознанно, а не наугад.
- Перечень доверенных адресов и подсетей: белые списки для мониторинга, платёжных колбэков, интеграций и офисных сетей.
- Инструкция дежурному: как отличить легитимный всплеск от атаки и как включить щадящий режим.
- Регламент реакции: кто снимает лимит, кого уведомляют, когда порог повышают, а когда режут жёстче.
- Сценарии нагрузочного прогона — на них подтверждается, что законные пики проходят, а грубый перебор получает отказ.
- Журнал изменений лимитов: дата, причина, кто согласовал, — видно, откуда взялось текущее значение.
Как это поддерживать без нас
Пороги живут в одном файле и меняются без переписывания логики. Инструкция и регламент обновляются вместе со схемой, поэтому новый инженер входит в контур за вечер, а не за неделю.
Кейс: как интернет-магазин прошёл пик распродажи
Пиковая распродажа — день, когда инфраструктура интернет-магазина проверяется по-настоящему: поток растёт в разы за минуты, и всё, что не выдержало, видно сразу. Ниже — цифры из выгрузок мониторинга до и после внедрения ограничения частоты запросов на входном узле на nginx.
Что было до
В момент старта акции входной узел принимал весь поток без разбора: доля успешных запросов падала до 62%, время отклика в пике доходило до 9 секунд — покупатель закрывал каталог раньше, чем получал ответ. Часть трафика составляли боты: они обходили каталог и набивали корзины, занимая все рабочие процессы приложения.
Серверных ошибок стало в 40 раз больше, чем в обычный день, а разбирались с этим уже после акции, по логам.
Что стало после
Лимиты развели по уровням: жёсткий порог на адрес источника для поиска и оформления заказа, мягкий — с очередью и задержкой для каталога и картинок, отдельный профиль для поисковых роботов. Доля успешных запросов на пике выросла до 99,4%, время отклика не выходило за 1,2 секунды, число серверных ошибок сократилось на порядок — при том же потоке покупателей.
Срабатывания видно в выгрузке мониторинга по имени правила, поэтому ложную блокировку снимают одной правкой, без перезапуска сервиса. Пороги подбирались по реальному профилю трафика и пересматривались после каждой репетиции нагрузки; конфигурация версионируется вместе с остальной инфраструктурой, и на следующей распродаже результат воспроизводится.
Чем общий лимит отличается от лимита на конкретный адрес
Общий лимит задаёт один потолок на весь сервис: ключом учёта служит константа, поэтому все запросы падают в общий счётчик. Такой режим ловит равномерный избыточный поток и аварии, когда трафик вырос из-за сбоя у клиента или ошибки в интеграции. Зато он пропускает перекос: если один адрес забирает девять десятых квоты, остальные получают отказы, хотя суммарный порог формально не превышен.
Лимит по адресу клиента считает каждый источник отдельно, и превышение одним не бьёт по остальным. Здесь видны частые опросы, автоматический сбор данных, забытый тестовый контур с повторными запросами. А вот распределённый поток с сотен адресов такой режим пропускает: каждый укладывается в свою квоту, а суммарная нагрузка на сервис остаётся разрушительной.
Выбор ключа ограничения зависит от того, что защищаем: для внешнего интерфейса берут адрес, для внутренних вызовов — идентификатор клиента или маршрут, для дорогих операций — комбинацию признаков. Рядом настраивают режимы учёта запросов: отдельно среднюю скорость и отдельно допустимый всплеск. Иначе легитимный запуск приложения, который сразу шлёт серию запросов, отбрасывается наравне с атакой.
На практике оба режима держат вместе: общий работает предохранителем на весь сервис, лимит по адресу — защитой от конкретного источника. Что пропускает лимит, зависит и от того, что считать одним запросом: если обращения к кэшируемым маршрутам в подсчёт не идут, порог можно опустить без риска для живых пользователей.
Технические сомнения: ключ клиента, всплески и белые списки
Пять сомнений, которые всплывают перед ограничением частоты запросов — по каждому есть отработанное решение.
Что брать ключом учёта: адрес, токен или маршрут?
Базовый ключ — адрес клиента, но за прокси он подменяется, поэтому берём реальный адрес из заголовка пересылки. Для API ключ строится по токену, для тяжёлых маршрутов — по паре «адрес + маршрут»: всплеск в поиске не роняет вход.
Как отличить ложное срабатывание от настоящей нагрузки?
Сначала режим наблюдения: правила считают запросы и пишут в лог, но не отклоняют. За неделю видно, какой доле клиентов достаётся отказ, и по каким маршрутам. Чаще всего это страницы с подгрузкой ресурсов — ключ или всплеск правим точечно.
Не начнут ли обычные посетители получать отказы?
Спокойный просмотр даёт единичные запросы в секунду, лимит ставим на порядок выше. Всплеск допускает короткую серию, поэтому страница с десятком файлов грузится целиком. Отказ получает автоматика, а не человек.
Можно ли включить на живом сервисе без простоя?
Конфигурация применяется перечитыванием, уже открытые соединения не рвутся. Правило вводим сначала на одном маршруте или части узлов, смотрим на долю отказов и время ответа, затем раскатываем. Откат — снятие правила тем же перечитыванием.
Как быть с доверенными источниками?
Мониторинг, служебные проверки и партнёрские интеграции выносим в отдельные зоны с высокими порогами, а не в полное исключение. Доверенный адрес не становится дырой: при аномалии ограничение всё равно сработает. Список живёт рядом с правилами и проходит ревью при каждом изменении.
Обсудим вашу нагрузку и вернёмся с оценкой и планом
Обсуждение задачи по ограничению частоты запросов идёт быстрее, когда есть факты о нагрузке, а не только описание симптомов. Разбираем их вместе с топологией контура и договариваемся, на каком уровне ставить лимиты: на входе перед прокси, внутри него по маршрутам или в самом приложении.
Полезно подготовить к разговору:
- профиль пиков: суточные и недельные максимумы, всплески от рассылок, доля анонимного и служебного трафика;
- схема контура: где стоит балансировщик и прокси, сколько узлов приложений, есть ли кэш и очередь;
- перечень публичных точек входа и методов, которые нельзя ограничивать одинаково;
- история инцидентов: когда и на чём падало, какие запросы выглядели как перебор или массовый парсинг;
- ожидаемый рост: планируемые запуски, сезонность, новые интеграции и мобильные клиенты;
- доступ к тестовому контуру, чтобы проверять правила до выкладки на рабочий.
Из этого разбора складывается оценка объёма работ и план внедрения по этапам. Начинаем с режима наблюдения: правила считают превышения, но не блокируют, и видно, кого задевает. Затем включаем отказ с понятными кодами ответа и заголовками, задаём отдельные пороги для критичных маршрутов. Следующие шаги — пилот на одном сервисе, замер доли отбитых запросов и времени ответа, раскатка на остальные узлы.







