Nginx - co robi opcja nodelay przy ograniczaniu żądań?

11

Dzięki modułowi HttpLimitReq nginx żądania mogą być ograniczone przez IP. Nie rozumiem jednak, co robi opcja „nodelay”.

Jeśli nadmierne żądania w ramach limitu opóźnień serii nie są konieczne, należy skorzystać z opcji nodelay

limit_req   zone=one  burst=5  nodelay;
Xeoncross
źródło

Odpowiedzi:

11

Dokumentacja tutaj zawiera wyjaśnienie, które brzmi jak to, co chcesz wiedzieć:

Dyrektywa określa strefę (strefę) i maksymalne możliwe serie żądań (seria). Jeśli szybkość przekracza wymagania określone w strefie, żądanie jest opóźniane, aby zapytania były przetwarzane z określoną prędkością

Z tego, co rozumiem, żądania dotyczące serii będą opóźnione (poświęć więcej czasu i poczekaj, aż zostaną obsłużone), z nodelayopcjami opóźnienie nie jest używane, a nadmiarowe żądania są odrzucane z błędem 503.

Ten post na blogu ( archive.org ) dobrze wyjaśnia, w jaki sposób działa ograniczenie prędkości na nginx:

Jeśli jesteś podobny do mnie, prawdopodobnie zastanawiasz się, co naprawdę oznacza ten wybuch. Oto sztuczka: zamień słowo „seria” na „wiadro” i załóż, że każdy użytkownik otrzymuje wiadro z 5 tokenami. Za każdym razem, gdy przekroczą stawkę 1 żądania na sekundę, muszą zapłacić token. Po wydaniu wszystkich swoich tokenów pojawia się komunikat o błędzie HTTP 503, który zasadniczo stał się standardem „wycofaj się, stary!”.

rdzeń rdzeniowy
źródło
4
Myślę, że się mylisz, instrukcja nginx stwierdza: „Nadmierne żądania są opóźniane, dopóki ich liczba nie przekroczy maksymalnego rozmiaru serii”. Zauważ, że dopóki nie przekroczy maksymalnej serii, ma ona zupełnie inne znaczenie niż ta , którą powiedziałeś. Ty również skonflikowałeś serię z nadmiarem żądań , uważam, że nadmiar żądań oznacza, że ​​jest powyżej strefy, podczas gdy może nadal być poniżej maksymalnej serii .
Hendy Irawan,
10

TL; DR: Opcja nodelay jest przydatna, jeśli chcesz narzucić limit prędkości bez ograniczania dozwolonych odstępów między żądaniami.

Trudno mi było przetrawić inne odpowiedzi, a następnie odkryłem nową dokumentację od Nginx z przykładami, które odpowiadają na to: https://www.nginx.com/blog/rate-limiting-nginx/

Oto istotna część. Dany:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

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

Parametr seryjny określa liczbę żądań, które klient może wykonać przekraczając szybkość określoną przez strefę (w naszej przykładowej strefie mylimit limit prędkości wynosi 10 żądań na sekundę lub 1 na 100 milisekund). Żądanie, które przychodzi wcześniej niż 100 milisekund po tym, jak poprzednie zostało umieszczone w kolejce, a tutaj ustawiamy rozmiar kolejki na 20.

Oznacza to, że jeśli 21 żądań dotrze jednocześnie z danego adresu IP, NGINX natychmiast przekazuje pierwsze do grupy serwerów nadrzędnych i umieszcza pozostałe 20 w kolejce. Następnie przekazuje żądanie w kolejce co 100 milisekund, a 503 zwraca klientowi tylko wtedy, gdy przychodzące żądanie powoduje, że liczba żądań w kolejce przekroczy 20.

Jeśli dodasz nodelay:

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

W przypadku parametru nodelay NGINX nadal przydziela przedziały w kolejce zgodnie z parametrem serii i nakłada skonfigurowany limit szybkości, ale nie poprzez rozdzielanie przekazywania żądań w kolejce. Zamiast tego, gdy żądanie dotrze „za wcześnie”, NGINX przekazuje je natychmiast, o ile w kolejce jest dostępne miejsce dla niego. Zaznacza ten slot jako „zajęty” i nie zwalnia go do wykorzystania przez kolejne żądanie, dopóki nie minie odpowiedni czas (w naszym przykładzie po 100 milisekundach).

Mark Woon
źródło
6

Widzę to następująco:

  1. Żądania będą obsługiwane tak szybko, jak to możliwe, aż do przekroczenia stawki strefy. Stawka strefy jest „średnio”, więc jeśli Twoja stawka jest 1r/sszybka 10, możesz mieć 10 żądań w 10 sekundowym oknie.

  2. Po przekroczeniu stawki strefy:

    za. Bez tego nodelaydalsze zapytania burstbędą opóźnione.

    b. Dzięki nodelay, kolejne żądania do burstbędą obsługiwane tak szybko, jak to możliwe.

  3. Po burstprzekroczeniu tego czasu serwer zwróci odpowiedź na błąd do momentu wygaśnięcia okna serii. np. w przypadku stawki 1r/si serii 10, klient będzie musiał czekać do 10 sekund na następne zaakceptowane żądanie.

Hendy Irawan
źródło
3

To ustawienie określa, czy żądania będą opóźnione, aby były zgodne z żądaną szybkością, czy też zostaną po prostu odrzucone ... w pewnym stopniu, czy ograniczeniem prędkości zarządza serwer, czy odpowiedzialność jest przekazywana klientowi.

nodelay obecny

Żądania będą rozpatrywane tak szybko, jak to możliwe; wszelkie żądania wysłane powyżej określonego limitu zostaną odrzucone z kodem ustawionym jakolimit_req_status

nodelay nieobecny (inaczej opóźniony)

Żądania będą obsługiwane z szybkością zgodną z określonym limitem. Na przykład, jeśli szybkość zostanie ustawiona na 10 req / s, każde żądanie zostanie obsłużone w ciągu> = .1 (1 / szybkość) sekund, co nie pozwoli na przekroczenie prędkości, ale pozwoli na utworzenie kopii zapasowej żądań. Jeśli wystarczająca liczba żądań z powrotem do przepełnienia segmentu (co byłoby również niemożliwe przez równoczesny limit połączeń), są one odrzucane z kodem ustawionym jako limit_req_status.

Krwawe szczegóły są tutaj: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L263 gdzie ta logika rozpoczyna się, gdy limit nie został jeszcze przekroczony, a teraz opóźnienie opcjonalnie zostanie zastosowany do żądania. Zastosowanie ma nodelayw szczególności zastosowanie dyrektywy: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L495 powodując, że delaypowyższa wartość wynosi 0, co powoduje, że moduł obsługi do natychmiastowego zwrócenia, NGX_DECLINEDktóry przekazuje żądanie do następnego modułu obsługi (zamiast tego, NGX_AGAINktóry będzie wymagał ponownego przetworzenia).

Matt Whipple
źródło
1

Nie zrozumiałem tego po raz pierwszy, kiedy czytałem wprowadzenie z https://www.nginx.com/blog/rate-limiting-nginx/ .

Teraz jestem pewien, że rozumiem, a moja odpowiedź jest jak dotąd najlepsza. :)

Załóżmy, że: 10r/sjest ustawiony, maksymalna zdolność serwera to np. 10000r/sKtóry jest 10r/msi jest w tej chwili tylko 1 klient.

Oto główna różnica między 10r/s per IP burst=40 nodelayi 10r/s per IP burst=40.

wprowadź opis zdjęcia tutaj

Jak udokumentowano na https://www.nginx.com/blog/rate-limiting-nginx/ ( zdecydowanie polecam najpierw przeczytać artykuł (z wyjątkiem sekcji Dwustopniowego ograniczania prędkości )), takie zachowanie rozwiązuje jeden problem. Który?:

W naszym przykładzie dwudziesty pakiet w kolejce czeka na przesłanie przez 2 sekundy, w którym to momencie odpowiedź na nie może być już przydatna dla klienta.

Sprawdź wersję roboczą, którą wykonałem, 40thżądanie otrzymuje odpowiedź o, 1spodczas gdy druga 40thotrzymuje odpowiedź o 4s.

To może najlepiej wykorzystać możliwości serwera: odsyła odpowiedzi tak szybko, jak to możliwe, jednocześnie zachowując x r/sograniczenie do danego klienta / adresu IP.

Ale tutaj też są koszty. Koszt będzie wynosić:

Jeśli masz wielu klientów w kolejce na serwerze, powiedzmy klient A, Bi C.

Bez nodelayżądania są obsługiwane w kolejności podobnej do ABCABCABC.
W nodelayprzypadku zamówienia jest bardziej prawdopodobne AAABBBCCC.


Chciałbym podsumować artykuł https://www.nginx.com/blog/rate-limiting-nginx/ tutaj.

Przede wszystkim najważniejsza jest konfiguracja x r/s.

  1. x r/s tylko nadmierne wnioski są natychmiast odrzucane.

  2. x r/s+ burst, nadmiarowe żądania są w kolejce.

1.vs 2., koszt jest taki, że po stronie klienta kolejki żądań podejmują ryzyko późniejszych żądań, które miały szansę zostać obsłużone.

Na przykład 10r/s burst=20vs 10r/sThe 11thprośba ma być natychmiast odrzucona na podstawie tego ostatniego warunku, ale teraz jest w kolejce i będzie służył. 11thŻądanie zajmuje 21thszansę życzenie użytkownika.

  1. x r/s+ burst+ nodelay, już wyjaśnione.

PS Rozdział dwustopniowego ograniczenia prędkości w artykule jest bardzo mylący. Nie rozumiem, ale to nie wydaje się mieć znaczenia.

Na przykład:

Po wprowadzeniu tej konfiguracji klient, który wysyła ciągły strumień żądań z prędkością 8 obr./s, doświadcza następującego zachowania.

8 r / s? poważnie? Obraz pokazuje 17 żądań w ciągu 3 sekund, 17/3 = 8?

Stóg
źródło