С nginx HttpLimitReq запросы модуля могут быть ограничены IP. Однако я не понимаю, что делает опция «nodelay».
Если избыточные запросы в пределах предельной задержки пакета не нужны, вы должны использовать nodelay
limit_req zone=one burst=5 nodelay;
TL; DR: Опция nodelay полезна, если вы хотите установить ограничение скорости без ограничения допустимого интервала между запросами.
Мне было трудно переваривать другие ответы, а затем я обнаружил новую документацию от Nginx с примерами, которые отвечают на это: https://www.nginx.com/blog/rate-limiting-nginx/
Вот важная часть. Дано:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
location /login/ {
limit_req zone=mylimit burst=20;
...
}
Параметр burst определяет, сколько запросов клиент может сделать сверх скорости, указанной в зоне (в нашем примере зоны mylimit ограничение скорости составляет 10 запросов в секунду или 1 каждые 100 миллисекунд). Запрос, который поступает раньше, чем через 100 миллисекунд после предыдущего, помещается в очередь, и здесь мы устанавливаем размер очереди на 20.
Это означает, что если с заданного IP-адреса одновременно поступает 21 запрос, NGINX немедленно пересылает первый из вышестоящих серверов и помещает оставшиеся 20 в очередь. Затем он пересылает запрос в очереди каждые 100 миллисекунд и возвращает 503 клиенту, только если входящий запрос заставляет количество запросов в очереди превысить 20.
Если вы добавите nodelay:
location /login/ {
limit_req zone=mylimit burst=20 nodelay;
...
}
С параметром nodelay NGINX по-прежнему выделяет слоты в очереди в соответствии с параметром пакета и накладывает настроенный предел скорости, но не за счет пересылки запросов в очереди. Вместо этого, когда запрос поступает «слишком рано», NGINX пересылает его немедленно, пока в очереди есть доступный слот. Он отмечает этот слот как «занятый» и не освобождает его для использования другим запросом до тех пор, пока не пройдет соответствующее время (в нашем примере - через 100 миллисекунд).
Документация Вот есть объяснение, похожее на то, что вы хотите знать:
Директива указывает зону (зону) и максимально возможные пачки запросов (пачки). Если скорость превышает требования, указанные в зоне, запрос задерживается, поэтому запросы обрабатываются с заданной скоростью.
Насколько я понимаю, запросы по пакету будут задерживаться (потребуется больше времени и подождать, пока они не будут обработаны), с nodelay
options задержка не используется, а лишние запросы отклоняются с ошибкой 503.
Это сообщение в блоге (archive.org) дает хорошее объяснение, как работает ограничение скорости на nginx:
Если вы похожи на меня, вам, вероятно, интересно, что на самом деле означает этот чертов взрыв. Вот уловка: замените слово «всплеск» на «ведро» и предположите, что каждому пользователю дается корзина с 5 токенами. Каждый раз, когда они превышают скорость 1 запроса в секунду, они должны платить токен. После того, как они потратили все свои токены, им выдается сообщение об ошибке HTTP 503, которое, по сути, стало стандартом для «отвали, чувак!».
Я вижу это следующим образом:
Запросы будут обрабатываться как можно быстрее, пока не будет превышена скорость зоны. Стоимость зоны "средняя", поэтому, если ваша ставка 1r/s
и лопнуть 10
вы можете получить 10 запросов в 10-секундном окне.
После превышения скорости зоны:
а. Без nodelay
, дальнейшие запросы до burst
будет отложено.
б. С участием nodelay
, дальнейшие запросы до burst
будут обслуживаться как можно быстрее.
После burst
превышено, сервер будет возвращать ошибку, пока не истечет пакетное окно. например для оценки 1r/s
и лопнуть 10
, клиенту потребуется подождать до 10 секунд следующего принятого запроса.
Этот параметр определяет, будут ли запросы задерживаться так, чтобы они соответствовали желаемой скорости, или они будут просто отклонены ... в некоторой степени, независимо от того, управляется ли ограничение скорости сервером или ответственность передается клиенту.
nodelay
настоящее времяЗапросы будут обработаны как можно быстрее; любые запросы, отправленные сверх указанного лимита, будут отклонены с кодом, установленным как limit_req_status
nodelay
отсутствует (иначе задерживается)Запросы будут обрабатываться со скоростью, соответствующей указанному пределу. Так, например, если скорость установлена в 10 запросов / с, то каждый запрос будет обрабатываться в течение> = 0,1 (1 / скорость) секунды, тем самым не позволяя превышение скорости, но позволяя выполнять резервное копирование запросов. Если резервное копирование достаточно запросов для переполнения корзины (чему также может препятствовать ограничение числа одновременных подключений), то они отклоняются с кодом, установленным как limit_req_status
.
Кровавые подробности здесь: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L263 где эта логика срабатывает, когда лимит еще не превышен, и теперь задержка может быть применена к запросу. Применение nodelay
в частности из директивы вступает в игру: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L495 вызывая ценность delay
выше, чтобы быть 0, вызывая немедленный возврат этого обработчика NGX_DECLINED
который передает запрос следующему обработчику (а не NGX_AGAIN
что фактически потребует повторной обработки).
Я не понял этого в первый раз, когда читал введение из https://www.nginx.com/blog/rate-limiting-nginx/.
Теперь я уверен, что понимаю, и мой ответ пока самый лучший. :)
Предположим: 10r/s
установлен, максимальная производительность сервера, например, 10000r/s
который 10r/ms
и на данный момент есть только 1 клиент.
Итак, вот основное различие между 10r/s per IP burst=40 nodelay
и 10r/s per IP burst=40
.
Поскольку https://www.nginx.com/blog/rate-limiting-nginx/ задокументировано (Я настоятельно рекомендую сначала прочитать статью(кроме Двухступенчатое ограничение скорости section)), такое поведение устраняет одну проблему. Который из?:
В нашем примере 20-й пакет в очереди ожидает пересылки в течение 2 секунд, после чего ответ на него может оказаться бесполезным для клиента.
Проверьте черновик, который я сделал, 40th
запрос получает ответ на 1s
а другой 40th
получает ответ на 4s
.
Это может наилучшим образом использовать возможности сервера: отправлять ответы как можно быстрее, сохраняя при этом x r/s
ограничение для данного клиента / IP.
Но здесь тоже есть цена. Стоимость составит:
Если у вас много клиентов в очереди на сервере, скажем, клиент A
, B
и C
.
Без nodelay
, запросы обслуживаются в порядке, аналогичном ABCABCABC
.
С участием nodelay
, заказ, скорее всего, будет AAABBBCCC
.
Подведу итоги статьи https://www.nginx.com/blog/rate-limiting-nginx/ Вот.
Прежде всего, самая важная конфигурация - это x r/s
.
x r/s
только лишние запросы немедленно отклоняются.
x r/s
+ burst
, лишние запросы ставятся в очередь.
1.
против 2.
, цена заключается в том, что на стороне клиента запросы в очереди имеют шансы на последующие повторные запросы, которые будут иметь шанс быть обслуженными.
Например, 10r/s burst=20
против 10r/s
, то 11th
запрос должен быть немедленно отклонен при последнем условии, но теперь он поставлен в очередь и будет обслужен. В 11th
запрос занимает 21th
шанс запроса.
x r/s
+ burst
+ nodelay
, уже объяснил.P.S. В Двухступенчатое ограничение скорости Раздел статьи очень запутанный. Я не понимаю, но это, кажется, не имеет значения.
Например:
При такой конфигурации клиент, который выполняет непрерывный поток запросов со скоростью 8 об / с, испытывает следующее поведение.
8 р / с? шутки в сторону? На изображении показано 17 запросов в течение 3 секунд, 17/3 = 8?