Nginx: ¿qué hace la opción nodelay al limitar las solicitudes?

11

Con el módulo nginx HttpLimitReq , las solicitudes pueden estar limitadas por IP. Sin embargo, no entiendo lo que hace la opción "nodelay".

Si el exceso de solicitudes dentro del límite de ráfaga de retardo no es necesario, debe usar el nodolay

limit_req   zone=one  burst=5  nodelay;
Xeoncross
fuente

Respuestas:

11

La documentación aquí tiene una explicación que suena como lo que quieres saber:

La directiva especifica la zona (zona) y las ráfagas máximas posibles de solicitudes (ráfaga). Si la tasa excede las demandas descritas en la zona, la solicitud se retrasa, por lo que las consultas se procesan a una velocidad determinada

Por lo que entiendo, las solicitudes durante la ráfaga se retrasarán (tome más tiempo y espere hasta que puedan ser atendidas), con las nodelayopciones no se utiliza el retraso y las solicitudes en exceso se rechazan con un error 503.

Esta publicación de blog ( archive.org ) da una buena explicación de cómo funciona la limitación de velocidad en nginx:

Si eres como yo, probablemente te estés preguntando qué significa realmente la explosión. Aquí está el truco: reemplace la palabra 'burst' con 'bucket', y suponga que cada usuario recibe un bucket con 5 tokens. Cada vez que exceden la tasa de 1 solicitud por segundo, tienen que pagar un token. Una vez que han gastado todos sus tokens, reciben un mensaje de error HTTP 503, que se ha convertido esencialmente en el estándar para 'retroceder, hombre'.

volcado de memoria
fuente
44
Creo que es incorrecto, el manual de nginx dice: "Las solicitudes excesivas se retrasan hasta que su número excede el tamaño máximo de ráfaga". Tenga en cuenta que hasta que exceda la ráfaga máxima es un significado completamente diferente que durante la ráfaga que dijo. También combinó ráfaga con exceso de solicitudes , creo que el exceso de solicitudes significa que está por encima de la zona, mientras que aún puede estar por debajo de la ráfaga máxima .
Hendy Irawan
10

TL; DR: la opción nodelay es útil si desea imponer un límite de velocidad sin restringir el espacio permitido entre las solicitudes.

Tuve dificultades para digerir las otras respuestas, y luego descubrí nueva documentación de Nginx con ejemplos que responden a esto: https://www.nginx.com/blog/rate-limiting-nginx/

Aquí está la parte pertinente. Dado:

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

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

El parámetro de ráfaga define cuántas solicitudes puede hacer un cliente por encima de la velocidad especificada por la zona (con nuestra zona de límite de muestra, el límite de velocidad es de 10 solicitudes por segundo, o 1 cada 100 milisegundos). Una solicitud que llega antes de los 100 milisegundos después de que la anterior se ponga en una cola, y aquí estamos configurando el tamaño de la cola en 20.

Eso significa que si 21 solicitudes llegan simultáneamente desde una dirección IP determinada, NGINX reenvía la primera al grupo de servidores en sentido ascendente de inmediato y coloca las 20 restantes en la cola. Luego reenvía una solicitud en cola cada 100 milisegundos y devuelve 503 al cliente solo si una solicitud entrante hace que el número de solicitudes en cola supere los 20.

Si agrega nodelay:

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

Con el parámetro nodelay, NGINX todavía asigna ranuras en la cola de acuerdo con el parámetro de ráfaga e impone el límite de velocidad configurado, pero no espaciando el reenvío de solicitudes en cola. En cambio, cuando una solicitud llega "demasiado pronto", NGINX la reenvía de inmediato siempre que haya un espacio disponible en la cola. Marca ese espacio como "tomado" y no lo libera para que lo use otra solicitud hasta que haya pasado el tiempo apropiado (en nuestro ejemplo, después de 100 milisegundos).

Mark Woon
fuente
6

La forma en que lo veo es la siguiente:

  1. Las solicitudes serán atendidas lo más rápido posible hasta que se exceda la tasa de zona. La tasa de zona es "en promedio", por lo que si su tasa es 1r/sy estalló 10, puede tener 10 solicitudes en una ventana de 10 segundos.

  2. Después de que se exceda la tasa de zona:

    a. Sin nodelay, burstse retrasarán más solicitudes hasta .

    si. Con nodelay, más solicitudes hasta burstserán atendidas lo más rápido posible.

  3. Una vez burstexcedido, el servidor devolverá la respuesta de error hasta que caduque la ventana de ráfaga. por ejemplo, para velocidad 1r/sy ráfaga 10, el cliente deberá esperar hasta 10 segundos para la próxima solicitud aceptada.

Hendy Irawan
fuente
3

La configuración define si las solicitudes se retrasarán para que se ajusten a la velocidad deseada o si simplemente serán rechazadas ... de alguna manera si el servidor gestiona la limitación de la velocidad o si la responsabilidad se transfiere al cliente.

nodelay presente

Las solicitudes serán atendidas lo más rápido posible; cualquier solicitud enviada por encima del límite especificado será rechazada con el código establecido comolimit_req_status

nodelay ausente (también conocido como retrasado)

Las solicitudes se manejarán a una velocidad que se ajuste al límite especificado. Entonces, por ejemplo, si se establece una tasa de 10 req / s, cada solicitud se manejará en> = .1 (1 / tasa) segundos, lo que no permite que se exceda la tasa, pero permite que las solicitudes sean respaldadas. Si se vuelven a realizar suficientes solicitudes para desbordar el depósito (que también se evitaría con un límite de conexión concurrente), se rechazarán con el código establecido como limit_req_status.

Los detalles sangrientos están aquí: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L263 donde esa lógica se activa cuando el límite aún no se ha pasado y ahora el retraso opcionalmente se aplicará a la solicitud. La aplicación de, nodelayen particular, de la directiva entra en juego aquí: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L495 provocando que el valor de delayarriba sea 0 provocando que controlador para devolver inmediatamente lo NGX_DECLINEDque pasa la solicitud al siguiente controlador (en lugar de NGX_AGAINlo que efectivamente solicitará que se procese nuevamente).

Matt Whipple
fuente
1

No lo entendí la primera vez cuando estaba leyendo la introducción de https://www.nginx.com/blog/rate-limiting-nginx/ .

Ahora estoy seguro de entender y mi respuesta es hasta ahora la mejor. :)

Supongamos: 10r/sestá configurado, la capacidad máxima del servidor es, por ejemplo, 10000r/scuál es 10r/msy solo hay 1 cliente en este momento.

Así que aquí está la principal diferencia entre 10r/s per IP burst=40 nodelayy 10r/s per IP burst=40.

ingrese la descripción de la imagen aquí

Como se documenta en https://www.nginx.com/blog/rate-limiting-nginx/ ( recomiendo leer primero el artículo (excepto la sección de limitación de velocidad en dos etapas )), este comportamiento soluciona un problema. ¿Cúal?:

En nuestro ejemplo, el paquete número 20 en la cola espera 2 segundos para ser reenviado, momento en el cual una respuesta podría no ser útil para el cliente.

Verifique el borrador que hice, la 40thsolicitud obtiene respuesta en 1smientras que el otro 40thobtiene respuesta en 4s.

Esto puede hacer el mejor uso de la capacidad del servidor: envía las respuestas lo más rápido posible mientras mantiene la x r/srestricción a un cliente / IP determinado.

Pero también hay un costo aquí. El costo será:

Si tiene muchos clientes haciendo cola en el servidor, digamos cliente A, By C.

Sin nodelay, las solicitudes se atienden en un orden similar a ABCABCABC.
Con nodelay, el orden es más probable que sea AAABBBCCC.


Me gustaría resumir el artículo https://www.nginx.com/blog/rate-limiting-nginx/ aquí.

Sobre todo, la configuración más importante es x r/s.

  1. x r/s solo, las solicitudes en exceso se rechazan de inmediato.

  2. x r/s+ burst, las solicitudes en exceso se ponen en cola.

1.vs 2., el costo es que en el lado del cliente, las solicitudes en cola aprovechan las posibilidades de solicitudes posteriores que habrán tenido la oportunidad de ser atendidas.

Por ejemplo, 10r/s burst=20vs 10r/s, 11thse supone que la solicitud debe ser rechazada inmediatamente bajo la última condición, pero ahora está en cola y será atendida. La 11thsolicitud aprovecha la 21thoportunidad de la solicitud.

  1. x r/s+ burst+ nodelay, ya explicado.

PD La sección de limitación de velocidad en dos etapas del artículo es muy confusa. No entiendo, pero eso no parece importar.

Por ejemplo:

Con esta configuración, un cliente que realiza un flujo continuo de solicitudes a 8 r / s experimenta el siguiente comportamiento.

8 r / s? ¿seriamente? Hay 17 solicitudes en 3 segundos que se muestran en la imagen, 17/3 = 8?

Almiar
fuente