Nginx - Что делает опция nodelay при ограничении запросов?

11

С помощью модуля nginx HttpLimitReq запросы могут быть ограничены по IP. Тем не менее, я не понимаю, что делает опция "nodelay".

Если лишние запросы в пределах предельной задержки пакета не нужны, вы должны использовать нодле

limit_req   zone=one  burst=5  nodelay;
Xeoncross
источник

Ответы:

11

Документация здесь имеет объяснение, которое звучит так, как вы хотите знать:

Директива указывает зону (зону) и максимально возможные пакеты запросов (пакет). Если скорость превышает требования, указанные в зоне, запрос задерживается, поэтому запросы обрабатываются с заданной скоростью.

Из того, что я понимаю, запросы по пакету будут задерживаться (занимают больше времени и ждут, пока они не будут обслужены), с nodelayопциями задержка не используется и лишние запросы отклоняются с ошибкой 503.

Этот пост в блоге ( archive.org ) дает хорошее объяснение, как работает ограничение скорости на nginx:

Если вы похожи на меня, вы, вероятно, задаетесь вопросом, что же на самом деле означает взрыв. Вот хитрость: замените слово «взрыв» на «ведро» и предположите, что каждому пользователю дается ведро с 5 токенами. Каждый раз, когда они превышают скорость 1 запроса в секунду, они должны платить токен. После того, как они потратили все свои токены, им выдается сообщение об ошибке HTTP 503, которое, по сути, стало стандартом для «отступай, человек!».

CoreDump
источник
4
Я думаю, что вы не правы, руководство nginx гласит: «Избыточные запросы задерживаются, пока их количество не превысит максимальный размер пакета». Обратите внимание, что до тех пор , пока не будет превышен максимальный пакет, значение будет совершенно другим, чем для пакета, который вы сказали Вы также связали пакет с избыточными запросами , я полагаю, что избыточные запросы означают, что он находится выше зоны, хотя он все еще может быть ниже максимального пакета .
Хенди Ираван
10

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 zone ограничение скорости составляет 10 запросов в секунду или 1 каждые 100 миллисекунд). Запрос, который приходит раньше, чем через 100 миллисекунд после того, как предыдущий был помещен в очередь, и здесь мы устанавливаем размер очереди равным 20.

Это означает, что если 21 запрос поступает с данного IP-адреса одновременно, NGINX немедленно перенаправляет первый запрос в вышестоящую группу серверов и помещает оставшиеся 20 в очередь. Затем он пересылает запрос в очереди каждые 100 миллисекунд и возвращает 503 клиенту только в том случае, если во входящем запросе количество запросов в очереди превысит 20.

Если вы добавите nodelay:

location /login/ {
  limit_req zone=mylimit burst=20 nodelay;
  ...
}

С параметром nodelay NGINX по-прежнему выделяет слоты в очереди в соответствии с параметром пакета и накладывает настроенное ограничение скорости, но не путем разнесения пересылки запросов в очереди. Вместо этого, когда запрос приходит «слишком рано», NGINX пересылает его немедленно, если в очереди для него есть доступный слот. Он помечает этот слот как «занятый» и не освобождает его для использования другим запросом до тех пор, пока не пройдет соответствующее время (в нашем примере, после 100 миллисекунд).

Марк Вун
источник
6

Я вижу это следующим образом:

  1. Запросы будут обрабатываться как можно быстрее, пока не будет превышен уровень зоны. Уровень зоны «в среднем», поэтому, если ваша скорость равна 1r/sнулю, 10вы можете получить 10 запросов в 10-секундном окне.

  2. После превышения нормы зоны:

    а. Без nodelay, дальнейшие запросы до burstбудут задерживаться.

    б. При этом nodelayдальнейшие запросы burstбудут обрабатываться как можно быстрее.

  3. После burstпревышения, сервер будет возвращать ответ об ошибке до тех пор, пока не истечет срок действия окна пакета. например, для скорости 1r/sи пакета 10, клиент должен будет ждать до 10 секунд для следующего принятого запроса.

Хенди ираван
источник
3

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

nodelay настоящее время

Запросы будут обработаны как можно быстрее; любые запросы, отправленные сверх указанного лимита, будут отклонены с кодом, установленным какlimit_req_status

nodelay отсутствует (он же задерживается)

Запросы будут обрабатываться со скоростью, соответствующей указанному пределу. Так, например, если скорость установлена ​​в 10 req / s, то каждый запрос будет обрабатываться в течение> = .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который будет эффективно требовать его повторной обработки).

Мэтт Уиппл
источник
1

Я не понял этого в первый раз, когда читал вступление от 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/ ( я настоятельно рекомендую сначала прочитать статью (кроме раздела « Двухступенчатое ограничение скорости »)), это поведение устраняет одну проблему. Который из?:

В нашем примере 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.

  1. x r/s только лишние запросы немедленно отклоняются.

  2. x r/s+ burst, лишние запросы ставятся в очередь.

1.vs 2.стоимость заключается в том, что на стороне клиента запросы в очереди берут на себя шансы последующих запросов, которые будут иметь возможность быть обслуженными.

Например, 10r/s burst=20против 10r/s, 11thпредполагается , что запрос будет отклонен немедленно при последнем условии, но теперь он ставится в очередь и будет обслуживаться. 11thЗапрос занимает 21thвозможность запроса.

  1. x r/s+ burst+ nodelay, Уже пояснялось.

PS Раздел « Двухступенчатое ограничение скорости » статьи очень запутанный. Я не понимаю, но это не имеет значения.

Например:

С этой конфигурацией клиент, выполняющий непрерывный поток запросов со скоростью 8 об / с, испытывает следующее поведение.

8 р / с? шутки в сторону? В течение 3 секунд показано 17 запросов, 17/3 = 8?

стог
источник