Nginx - Що робить опція nodelay при обмеженні запитів?


11

За допомогою модуля nginx HttpLimitReq запити можуть бути обмежені IP-адресою. Однак я не розумію, що робить варіант "nodelay".

Якщо надлишки запитів у межах граничної затримки не потрібні, слід скористатися вузлом

limit_req   zone=one  burst=5  nodelay;

Відповіді:


11

Документація тут має пояснення, яке звучить як те, що ви хочете знати:

Директива вказує зону (зону) та максимально можливі спалахи запитів (вривання). Якщо показник перевищує вимоги, викладені в зоні, запит затримується, тому запити обробляються із заданою швидкістю

З того, що я розумію, запити через пакет будуть затримані (зайняти більше часу та почекати, поки вони можуть бути подані), з nodelayпараметрами затримка не використовується, а зайві запити відхиляються з помилкою 503.

Цей запис у блозі ( archive.org ) дає хороші пояснення як працює обмеження швидкості на nginx:

Якщо ти схожий на мене, ти, напевно, цікавишся, що насправді значить вибух. Ось хитрість: замініть слово "лопнути" на "відро" і припустіть, що кожному користувачеві надається відро з 5 лексемами. Щоразу, коли вони перевищують швидкість 1 запиту в секунду, вони повинні сплачувати жетон. Після того, як вони витратили всі свої жетони, їм видається повідомлення про помилку HTTP 503, яке по суті стало стандартом для "відступай, чоловіче!".


4
Я думаю, що ви невірні, керівництво nginx зазначає: "Надмірна кількість запитів затримується, поки їх кількість не перевищить максимальний розмір". Зауважте, що поки не перевищить максимальний вибух, це зовсім інше значення, ніж над вибухом, який ви сказали. Ви також поєднали вибух із зайвими запитами , я вважаю, що надлишки запитів означають, що він знаходиться над зоною, хоча він все ще може бути нижче максимального .
Хенді Іраван

10

TL; DR: Параметр вузла корисний, якщо ви хочете встановити обмеження швидкості, не обмежуючи дозволений інтервал між запитами.

Інші відповіді мені важко було перетравити, і тоді я відкрив нову документацію від 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.

Це означає, що якщо 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 / rate) секунди, тим самим не дозволяючи перевищувати швидкість, але дозволяє запитам отримати резервне копіювання. Якщо достатньо запитів створити резервну копію для переповнення відра (що також було б перешкоджено одночасним обмеженням з'єднання), вони відхиляються з кодом, встановленим як limit_req_status.

Деталі про Gory тут: 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.проти 2., вартість полягає в тому, що на стороні клієнта запити, що стоять у черзі, приймають шанси на наступні reuqests, які мали б можливість отримати обслуговування.

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

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

PS Розділ статті про обмеження швидкості у двох ступенях дуже заплутаний. Я не розумію, але це, мабуть, не має значення.

Наприклад:

За умови встановлення такої конфігурації клієнт, який здійснює безперервний потік запитів при 8 об / х, відчуває таку поведінку.

8 р / с? серйозно? На зображенні показано 17 запитів протягом 3 секунд, 17/3 = 8?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.