# конспект · шаг 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на точке входа бесполезен против перебора: сотня попыток проходит до начала ограничений.
Комментарии
Пока нет комментариев. Будь первым!
Оставить комментарий