Nginx - Que fait l'option nodelay lors de la limitation des demandes?

11

Avec le module nginx HttpLimitReq, les requêtes peuvent être limitées par IP. Cependant, je ne comprends pas ce que fait l'option "nodelay".

Si les demandes en excès dans le délai de rafale limite ne sont pas nécessaires, vous devez utiliser le nodelay

limit_req   zone=one  burst=5  nodelay;
Xeoncross
la source

Réponses:

11

La documentation ici a une explication qui ressemble à ce que vous voulez savoir:

La directive spécifie la zone (zone) et le nombre maximal de rafales de requêtes possibles (rafale). Si le taux dépasse les demandes décrites dans la zone, la demande est retardée, de sorte que les requêtes sont traitées à une vitesse donnée

D'après ce que je comprends, les demandes au cours de la rafale seront retardées (prendre plus de temps et attendre qu'elles puissent être servies), avec les nodelayoptions le délai n'est pas utilisé et les demandes en excès sont refusées avec une erreur 503.

Ce billet de blog ( archive.org ) donne une bonne explication sur le fonctionnement de la limitation de débit sur nginx:

Si vous êtes comme moi, vous vous demandez probablement ce que signifie vraiment l'éclatement. Voici l'astuce: remplacez le mot «burst» par «bucket», et supposez que chaque utilisateur se voit attribuer un bucket avec 5 jetons. Chaque fois qu'ils dépassent le taux de 1 demande par seconde, ils doivent payer un jeton. Une fois qu'ils ont dépensé tous leurs jetons, ils reçoivent un message d'erreur HTTP 503, qui est essentiellement devenu la norme pour `` reculer, homme! ''.

coredump
la source
4
Je pense que vous avez tort, le manuel nginx déclare: "Les demandes excessives sont retardées jusqu'à ce que leur nombre dépasse la taille maximale de rafale". Notez que jusqu'à ce que dépasse la rafale maximale est une signification entièrement différente de celle de la rafale que vous avez dite. Vous avez également confondu la rafale avec des demandes en excès , je pense que les demandes en excès signifient qu'elle est au-dessus de la zone, alors qu'elle peut toujours être inférieure à la rafale maximale .
Hendy Irawan
10

TL; DR: L'option nodelay est utile si vous souhaitez imposer une limite de débit sans restreindre l'espacement autorisé entre les demandes.

J'ai eu du mal à digérer les autres réponses, puis j'ai découvert une nouvelle documentation de Nginx avec des exemples qui répondent à ceci: https://www.nginx.com/blog/rate-limiting-nginx/

Voici la partie pertinente. Donné:

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

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

Le paramètre burst définit le nombre de demandes qu'un client peut effectuer au-delà du taux spécifié par la zone (avec notre exemple de zone mylimit, la limite de débit est de 10 demandes par seconde, soit 1 toutes les 100 millisecondes). Une requête qui arrive plus tôt que 100 millisecondes après que la précédente ait été placée dans une file d'attente, et ici nous mettons la taille de la file d'attente à 20.

Cela signifie que si 21 requêtes arrivent simultanément à partir d'une adresse IP donnée, NGINX transfère immédiatement la première au groupe de serveurs en amont et place les 20 restantes dans la file d'attente. Il transfère ensuite une demande en file d'attente toutes les 100 millisecondes et renvoie 503 au client uniquement si une demande entrante fait dépasser le nombre de demandes en file d'attente de 20.

Si vous ajoutez nodelay:

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

Avec le paramètre nodelay, NGINX alloue toujours des créneaux dans la file d'attente en fonction du paramètre de rafale et impose la limite de débit configurée, mais pas en espaçant le transfert des demandes en file d'attente. Au lieu de cela, lorsqu'une demande arrive «trop tôt», NGINX la transmet immédiatement tant qu'il y a un emplacement disponible pour elle dans la file d'attente. Il marque cet emplacement comme «pris» et ne le libère pas pour une autre demande jusqu'à ce que le temps approprié se soit écoulé (dans notre exemple, après 100 millisecondes).

Mark Woon
la source
6

La façon dont je le vois est la suivante:

  1. Les demandes seront traitées le plus rapidement possible jusqu'à ce que le taux de zone soit dépassé. Le taux de zone est "en moyenne", donc si votre taux est 1r/set éclaté, 10vous pouvez avoir 10 demandes en 10 secondes.

  2. Une fois le taux de zone dépassé:

    une. Sans cela nodelay, les demandes ultérieures burstseront retardées.

    b. Avec nodelay, les demandes jusqu'à burstseront traitées le plus rapidement possible.

  3. Une fois la valeur burstdépassée, le serveur renvoie une réponse d'erreur jusqu'à l'expiration de la fenêtre de rafale. Par exemple, pour le débit 1r/set la rafale 10, le client devra attendre jusqu'à 10 secondes pour la prochaine demande acceptée.

Hendy Irawan
la source
3

Le paramètre définit si les demandes seront retardées afin qu'elles soient conformes au débit souhaité ou si elles seront simplement rejetées ... quelque peu si la limitation du débit est gérée par le serveur ou si la responsabilité est transférée au client.

nodelay présent

Les demandes seront traitées le plus rapidement possible; toute demande envoyée au-delà de la limite spécifiée sera rejetée avec le code défini commelimit_req_status

nodelay absent (alias retardé)

Les demandes seront traitées à un taux conforme à la limite spécifiée. Ainsi, par exemple, si un débit est défini sur 10 req / s, chaque demande sera traitée en> = 0,1 (1 / débit) secondes, ce qui ne permettra pas de dépasser le débit, mais permettra de sauvegarder les demandes. Si suffisamment de demandes de sauvegarde pour déborder le compartiment (ce qui serait également empêché par une limite de connexion simultanée), elles sont rejetées avec le code défini comme limit_req_status.

Les détails sanglants sont ici: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L263 où cette logique entre en jeu lorsque la limite n'a pas encore été dépassée et maintenant le retard va éventuellement être appliqué à la demande. L'application de nodelaynotamment de la directive entre en jeu ici: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L495 provoquant la valeur de delayci - dessus à 0 déclenchant cela gestionnaire pour renvoyer immédiatement NGX_DECLINEDce qui transmet la demande au gestionnaire suivant (plutôt que NGX_AGAINqui le remettra effectivement en attente pour être traité à nouveau).

Matt Whipple
la source
1

Je n'ai pas compris cela lors de la première lecture de l'introduction de https://www.nginx.com/blog/rate-limiting-nginx/ .

Maintenant, je suis sûr de comprendre et ma réponse est jusqu'à présent la meilleure. :)

Supposons que: 10r/sest défini, la capacité maximale du serveur est par exemple 10000r/sce qui est 10r/mset il n'y a qu'un seul client pour le moment.

Voici donc la principale différence entre 10r/s per IP burst=40 nodelayet 10r/s per IP burst=40.

entrez la description de l'image ici

Comme le https://www.nginx.com/blog/rate-limiting-nginx/ l'a documenté ( je recommande fortement de lire l'article en premier (sauf la section de limitation de débit en deux étapes )), ce comportement résout un problème. Laquelle?:

Dans notre exemple, le 20e paquet dans la file d'attente attend 2 secondes pour être transféré, auquel cas une réponse à celui-ci pourrait ne plus être utile au client.

Vérifiez le brouillon que j'ai fait, la 40thdemande obtient une réponse pendant 1sque l'autre 40thobtient une réponse à 4s.

Cela peut faire le meilleur usage de la capacité du serveur: renvoie des réponses aussi rapidement que possible tout en conservant la x r/scontrainte à un client / IP donné.

Mais il y a aussi un coût ici. Le coût sera:

Si plusieurs clients font la queue sur le serveur, disons client A, Bet C.

Sans nodelay, les demandes sont servies dans un ordre similaire à ABCABCABC.
Avec nodelay, l'ordre est plus susceptible d'être AAABBBCCC.


Je voudrais résumer l'article https://www.nginx.com/blog/rate-limiting-nginx/ ici.

Surtout, la configuration la plus importante est x r/s.

  1. x r/s seulement, les demandes excédentaires sont rejetées immédiatement.

  2. x r/s+ burst, les demandes en excès sont mises en file d'attente.

1.vs 2., le coût est que du côté client, les requêtes en file d'attente saisissent les chances de demandes ultérieures qui auront eu la chance d'être servies.

Par exemple, 10r/s burst=20vs 10r/s, la 11thdemande est censée être rejetée immédiatement dans cette dernière condition, mais maintenant elle est mise en file d'attente et sera traitée. La 11thdemande prend 21thsa chance.

  1. x r/s+ burst+ nodelay, déjà expliqué.

PS La section de limitation de débit en deux étapes de l'article est très déroutante. Je ne comprends pas, mais cela ne semble pas avoir d'importance.

Par exemple:

Avec cette configuration en place, un client qui effectue un flux continu de demandes à 8 tr / s rencontre le comportement suivant.

8 r / s? sérieusement? Il y a 17 demandes dans les 3 secondes affichées dans l'image, 17/3 = 8?

Meule
la source