1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6

# конспект · шаг 6 из 6

Конспект: limit_req и дырявое ведро

выжимка - её можно унести в заметки

Ограничение частоты - дырявое ведро, а не квота за календарную секунду.

Зона и лимит

# в http:
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

# в location:
limit_req zone=login burst=10 nodelay;
limit_req_status 429;
Часть Что задаёт
$binary_remote_addr ключ: по чему считаем (адрес в бинарном виде - вчетверо компактнее)
zone=login:10m имя и память под состояния (~160 000 адресов на 10 МБ)
rate=5r/m скорость вытекания ведра
burst=10 сколько запросов может подождать в очереди
nodelay пропустить очередь сразу, но не превышая ведро

Почему при rate=1r/s из десяти одновременных проходит один

rate - это скорость вытекания. Ведро без burst вмещает один запрос: девять остальных получают отказ немедленно, а не «в течение секунды».

Настройка Поведение
без burst всё сверх скорости - сразу отказ
burst=N до N запросов ждут своей очереди (задержка)
burst=N nodelay до N проходят сразу, но ведро всё равно наполняется
delay=M первые M без задержки, остальные ждут

Как внедрять безопасно

limit_req_dry_run on;      # считать и логировать, но не отказывать

Посмотреть по логам, кого бы отсекли, - и только потом включать по-настоящему.

Ловушки джокера

  • Одно ведро на все location с этой зоной. Ключ и зона - это состояние, а не свойство location: три limit_req zone=api в разных местах считают вместе.
  • Ключ за прокси. Без realip все клиенты придут с одного адреса и получат общий лимит. Никогда не считать по $http_x_forwarded_for - он подделывается.
  • 503 вместо 429. Умолчание - 503, а клиенты и мониторинг ждут 429: ставь limit_req_status 429.
  • limit_conn - про соединения, а не про запросы: он ограничивает одновременные скачивания, а не частоту.

Что показал стенд

Десять одновременных запросов при rate=1r/s:

настройка коды времена
без burst 200 x1, 503 x9 все мгновенно
burst=3 200 x4, 503 x6 трое ждали 1, 2 и 3 с
burst=3 nodelay 200 x4, 503 x6 все мгновенно
burst=5 delay=2 (8 запросов) 200 x6, 503 x2 двое сразу, трое по очереди
limit_req_status 429 200 x1, 429 x9 -
limit_req_dry_run on 200 x10 в логе девять строк «dry run»

Пять одновременных скачиваний при limit_conn 2 - 200 x2 и 503 x3. rate=30r/m - это один запрос раз в две секунды, а не тридцать в начале минуты. max_headers 5: два заголовка 200, двенадцать - 400.

Ловушки джокера

  • limit_req в блоке с return 200 не работает: return идёт на фазе rewrite, лимит - на preaccess. Проверять надо на отдаче файла или бэкенде.
  • limiting requests пишется на уровне error, delaying request - на warn, и означают они противоположное.
  • Ключ из X-Forwarded-For даёт боту новое ведро на каждый запрос; ключ берут $binary_remote_addr после realip с узким списком доверия.
  • Пустое значение ключа выключает лимит - на этом строят белые списки через map.
  • Большой burst на точке входа бесполезен против перебора: сотня попыток проходит до начала ограничений.

Комментарии

Пока нет комментариев. Будь первым!

Оставить комментарий

Комментарий появится после проверки. Email не публикуется. Войти, чтобы не вводить имя каждый раз.