Jak skonfigurować nginx, aby zwracał kod 429 http podczas ograniczania prędkości?

11

Jak skonfigurować nginx, aby zwracał kod stanu HTTP 429 (Zbyt wiele żądań) zamiast domyślnego 503 (Usługa niedostępna) podczas ograniczania / ograniczania prędkości?

Do Twojej wiadomości używam nginx jako odwrotnego proxy z HttpLimitReqModule. Wersja robocza specyfikacji dla kodu statusu 429 to RFC6585 .

To (zamknięte) pytanie dotyczące zmiany stosu pokazuje, że można użyć dyrektywy error_page . Jednak ja nie chce wrócić do 429 czy rzeczywiście istnieje problem z serwerem (nie klient trafiając nas zbyt dużo) i serwer powinien być powrót 503 Usługa niedostępna.

Jakieś sugestie?

adambrod
źródło
Do Twojej wiadomości, stworzyłem prośbę o ulepszenie tej funkcji, ponieważ nie jest to możliwe bez mapowania wszystkich 503 na 429.
adambrod

Odpowiedzi:

19

Dobre wieści, w wersji 1.3.15 http://mailman.nginx.org/pipermail/nginx/2013-March/038306.html

mamy dyrektywy „limit_req_status” i „limit_conn_status”. Właśnie przetestowałem je na Gentoo Linux (zauważ, że musisz mieć skompilowane moduły limit_req i limit_con).

Dzięki tym ustawieniom myślę, że możesz osiągnąć to, o co prosiłeś:

limit_req_status 429;
limit_conn_status 429;

Sprawdziłem to szybko:

ab2 -n 100000 -c 55 "http://127.0.0.1/api/v1

W przypadku których większość żądań zakończyła się niepowodzeniem po aktywowaniu dyrektywy z powodu wysokiej częstotliwości żądań i skonfigurowanego limitu w nginx:

limit_req zone=api burst=15 nodelay;
Vanthome
źródło
1
.. czym jest „ab2”?
XXL,
1
abjest narzędziem od apache2-utils. na Ubuntu jest, abale pod CentOs tak ab2.
dieter
1

Na podstawie odpowiedzi VBart i innych komentarzy jasne jest, że najlepszą opcją jest zmapowanie błędów 503 na 429s.

error_page 503 = 429 /too-many-requests.html

Ponieważ nginx (1.3.x) używa tylko kodów stanu 503 dla limit_req i limit_conn, powinno to być dobre podejście.

adambrod
źródło
to nie jest najlepsza opcja. 429 jest szczególnym przypadkiem użycia, odwzorowanie wszystkich potencjalnych 503 (usługa niedostępna), aby zwrócić 429 jest mylące i nieważne dla użytkowników. Na przykład klient może zobaczyć 429 i użyć logiki ponownych prób wycofania, ale jeśli 503 nie jest związany z ograniczaniem, nie pomaga.
Eddie
0

Sam Nginx nigdy nie zwraca 503 w przypadkach innych niż limit_req i limit_conn.

VBart
źródło
1
Ach, to interesujące. Mówisz więc, że jeśli zamienię 503 na 429 za pomocą error_page, nigdy nie powiem klientom o zbyt wielu żądaniach, chyba że naprawdę wysyłają zbyt wiele żądań?
adambrod
Tak, prawda, ale z jednym wyjątkiem, którego nie masz (proxy/factcgi/scgi/uwsgi)_intercept_errorswłączonego. nginx.org/r/proxy_intercept_errors
VBart
Możliwe jest również, że aplikacja obsługiwana przez nginx zwróci 503, co utrudnia klientowi sprawdzenie, czy jest to limit połączenia z nginx lub błąd serwera z aplikacji.
bbaja42