![Die Ratenbegrenzung von Nginx funktioniert nicht wie erwartet](https://rvso.com/image/1684440/Die%20Ratenbegrenzung%20von%20Nginx%20funktioniert%20nicht%20wie%20erwartet.png)
Ich versuche, die Nginx-Verbindungen zu begrenzen, aber es scheint nicht wie erwartet zu funktionieren. Ich habe versucht, es mit 2 und 10 Anfragen pro Sekunde zu testen.
Erstens: 2 Anfragen pro Sekunde
limit_req_zone $binary_remote_addr zone=myzone:10m rate=2r/s;
limit_req_status 429;
server {
listen *:80;
server_name 172.23.97.94;
root /var/www/html;
index index.html;
location / {
limit_req zone=myzone;
try_files $uri $uri/ =404;
}
}
Testen mit curl:
for i in {1..2}; do curl -I -s "http://172.23.97.94" | head -n 1; done
HTTP/1.1 200 OK
HTTP/1.1 429 Too Many Requests
Access.log bestätigt, dass es nur zwei Anfragen gleichzeitig gibt, die zweite Anfrage erhält jedoch 429:
172.23.106.65 - - [08/Feb/2023:17:10:35 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:10:35 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
Wenn ich die gleiche Anfrage jedoch mit einer Pause von 0,5 Sekunden mache, läuft es problemlos:
for i in {1..2}; do curl -I -s "http://172.23.97.94" | head -n 1; sleep 0.5; done
HTTP/1.1 200 OK
HTTP/1.1 200 OK
Zweitens, 10 Anfragen pro Sekunde
limit_req_zone $binary_remote_addr zone=myzone:10m rate=10r/s;
limit_req_status 429;
server {
listen *:80;
server_name 172.23.97.94;
root /var/www/html;
index index.html;
location / {
limit_req zone=myzone;
try_files $uri $uri/ =404;
}
}
Testen mit curl:
for i in {1..10}; do curl -I -s "http://172.23.97.94" | head -n 1; done
HTTP/1.1 200 OK
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
Access.log bestätigt, dass es nur 10 Verbindungen gleichzeitig gibt, aber nur die erste erhält 200:
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
Wenn ich jedoch dieselbe Anfrage mit einer Pause von 0,01 Sekunden mache, sind einige davon 200, während andere 429 sind:
for i in {1..10}; do curl -I -s "http://172.23.97.94/device/1" | head -n 1; sleep 0.01; done
HTTP/1.1 200 OK
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 200 OK
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 200 OK
Mache ich etwas falsch? Oder funktioniert die Ratenbegrenzung einfach nicht wie erwartet?
Antwort1
Ich bin auch auf dieses Problem gestoßen – 10r/s ist eigentlich eine Anfrage pro Zehntelsekunde.
Hier ist ein zugehöriger Stack Overflow-Beitrag:https://stackoverflow.com/questions/62262540/ideale-config-for-nginx-rate-limiting
Hier ist der Artikel von Nginx, auf den sie sich beziehen und in dem es um dieses Thema geht:https://www.nginx.com/blog/rate-limiting-nginx/
Das scheint mir eine schlechte Entscheidung zu sein, da es üblich ist, dass für eine Seite mehrere Ajax-Anfragen geladen werden und diese bei einer Ratenbegrenzung verzögert werden.
Dem Artikel zufolge gibt es Möglichkeiten, dies mit der Option „Nodelay“ zu umgehen und anschließend eine zweistufige Ratenbegrenzung durchzuführen.
limit_req zone=ip burst=12 delay=8;
Dadurch werden acht Anfragen gleichzeitig zugelassen. Anschließend werden sie verzögert, bis sich 12 in der Warteschlange befinden, und dann beginnen sie, sie abzulehnen.