Comment configurer nginx pour renvoyer le code http 429 lors de la limitation de débit?

11

Comment configurer nginx pour renvoyer le code d'état http 429 (Trop de demandes) au lieu du code 503 par défaut (Service non disponible) lors de la limitation / limitation de débit?

Pour info, j'utilise nginx comme proxy inverse avec le HttpLimitReqModule. Le projet de spécification pour le code d'état 429 est RFC6585 .

Ce (fermé) question sur les spectacles stackexchanged qu'il est possible d'utiliser la error_page directive. Cependant, je ne veux pas retourner un 429 s'il y a vraiment un problème de serveur (pas que le client nous frappe trop) et le serveur devrait retourner le service 503 non disponible.

Aucune suggestion?

Adambrod
la source
Pour info, j'ai créé une demande d'amélioration pour cette fonctionnalité car elle n'est pas possible sans mapper tous les 503 à 429.
adambrod

Réponses:

19

Bonne nouvelle, avec la version 1.3.15 http://mailman.nginx.org/pipermail/nginx/2013-March/038306.html

nous avons les directives "limit_req_status" et "limit_conn_status". Je viens de les tester sur Gentoo Linux (notez que vous devez avoir les modules limit_req et limit_con compilés).

Avec ces paramètres, je pense que vous pouvez réaliser ce que vous avez demandé:

limit_req_status 429;
limit_conn_status 429;

J'ai vérifié cela avec un rapide:

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

Sur lequel la plupart des demandes ont échoué après l'activation de la directive en raison du taux de demande élevé et de la limite configurée dans nginx:

limit_req zone=api burst=15 nodelay;
vanthome
la source
1
.. qu'est-ce que "ab2"?
XXL
abest un outil de apache2-utils. sur Ubuntu c'est le cas abmais sous CentOs c'est le cas ab2.
dieter
1

Sur la base de la réponse de VBart et d'autres commentaires, il est clair que la meilleure option est de mapper 503 erreurs à 429s.

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

Étant donné que nginx (1.3.x) n'utilise que 503 codes d'état pour limit_req et limit_conn, cela devrait être une bonne approche.

Adambrod
la source
ce n'est pas la meilleure option. Le 429 est un cas d'utilisation spécifique, le mappage de tous les 503 potentiels (service non disponible) pour renvoyer un 429 est trompeur et invalide pour les utilisateurs. Par exemple, un client peut voir un 429 et utiliser une logique de nouvelle tentative de back-off, mais si le 503 n'est pas lié à la limitation, cela n'aide pas.
Eddie
0

Nginx lui-même ne renvoie jamais 503 dans des cas autres que limit_req et limit_conn.

VBart
la source
1
Ah, c'est intéressant. Vous dites donc que si je remplace 503 par 429 en utilisant error_page, je ne dirai jamais trop de demandes aux clients, à moins qu'ils n'envoient vraiment trop de demandes?
adambrod
Oui, vrai, mais avec une seule exception, que vous n'avez pas (proxy/factcgi/scgi/uwsgi)_intercept_errorsactivé. nginx.org/r/proxy_intercept_errors
VBart
Il est également possible que l'application servie par nginx renvoie 503, ce qui rend difficile pour le client de voir s'il s'agit de la limite de connexion de nginx ou d'une erreur de serveur de l'application.
bbaja42