¿Por qué alguna vez establecerías MaxKeepAliveRequests en cualquier cosa menos ilimitada?

11

Apache KeepAliveTimeoutexiste para cerrar una conexión de mantenimiento si no se emite una nueva solicitud dentro de un período de tiempo determinado. Siempre que el usuario no cierre su navegador / pestaña, este tiempo de espera (generalmente de 5 a 15 segundos) es lo que finalmente cierra la mayoría de las conexiones de mantenimiento y evita que se desperdicien recursos del servidor al mantener las conexiones de forma indefinida.

Ahora, la MaxKeepAliveRequestsdirectiva establece un límite en el número de solicitudes HTTP que KeepAliveatenderá una única conexión TCP (abierta debido a ). Establecer esto en 0significa que se permite un número ilimitado de solicitudes.

¿Por qué pondrías esto en algo que no sea "ilimitado"? Siempre que un cliente siga haciendo solicitudes de forma activa, ¿qué daño hay al permitir que sucedan en la misma conexión de mantenimiento de vida? Una vez que se alcanza el límite, las solicitudes siguen llegando, solo en una nueva conexión.

Desde mi punto de vista, no tiene sentido limitar esto. ¿Qué me estoy perdiendo?

Jonathon Reinhart
fuente

Respuestas:

4

Básicamente, porque Apache no fue creado para ello. El problema es el uso de la memoria del servidor. En muchas configuraciones, la generación de contenido se realiza en el mismo proceso que la entrega de contenido, por lo que cada proceso crecerá al tamaño de lo más grande que maneja. Imagine un proceso que se expande a 64 MB debido a una secuencia de comandos php pesada, luego ese proceso hinchado se sienta y sirve archivos estáticos. Ahora multiplique eso por 100. Además, si hay pérdidas de memoria en cualquier lugar, los procesos crecerán sin límite.

La configuración de keepalive debe estar equilibrada según el tipo de contenido y el tráfico. En general, la configuración óptima tiene MaxKeepAliveRequests alto (100-500) y KeepAliveTimeout bajo (2-5) para liberarlos rápidamente.

Dirigible
fuente
2

Sé que esta es una vieja pregunta, pero he estado haciendo algunas depuraciones, y parece que (y esto no solo es cierto para Apache) MaxKeepAliveRequestsfunciona independientemente KeepAliveTimeout.

Es decir, la directiva de tiempo de espera solo cuenta contra las conexiones persistentes inactivas (sin lecturas ni escrituras): si sigue solicitando por debajo del tiempo de espera, prácticamente puede hacer una cantidad ilimitada de solicitudes a través de la misma conexión.

¿Esto podría no ser bueno por algunas razones, incluidas las conexiones tcp de larga ejecución que se eliminan al azar? En cualquier caso, los clientes http no son tan estúpidos y pueden manejar una MaxKeepAliveRequestsconfiguración "baja" bastante bien, por ejemplo, es relativamente fácil en el lenguaje de programación detectar si el servidor ha cerrado una conexión tcp y así volver a conectarse a ella. Además, la mayoría de los clientes http tendrán sus propios límites (por ejemplo, los navegadores cerrarían una conexión de mantenimiento después de unos 300 segundos).

lifeofguenter
fuente
1

Una razón sería para el equilibrio de carga. Una vez que se realiza una conexión persistente de mantenimiento o http 1.1, el equilibrador de carga no lo moverá a un nuevo host hasta que se cierre. Si tiene un cliente haciendo una gran cantidad de solicitudes a través de su única conexión, es posible que no obtenga un buen equilibrio entre los servidores.

dtauzell
fuente
¿Pero por qué eso importaría? Para mí, parece indeseable extender la conexión de un solo usuario a varios servidores. El equilibrio de carga es manejar una gran cantidad de usuarios, no conexiones de un solo usuario. De hecho, si un solo usuario está trabajando en un servicio, preferiría que se limitara a un solo servidor (donde efectivamente se limitarían).
Jonathon Reinhart
1
Buenos puntos. Algunas reflexiones: 1. cualquier otra persona en ese servidor también sería golpeada. 2. Para equilibradores de carga que funcionan por debajo del nivel HTTP: cuando saca un servidor del grupo de equilibradores de carga, no cierra la conexión HTTP existente. Eso hace que sea un poco más difícil mover a las personas a un servidor diferente con solo el equilibrador de carga. La razón 2 es cómo llegué a esta página mientras buscaba para ver lo que la gente tenía que decir sobre este parámetro.
dtauzell
1
Una tercera razón: si su servidor / aplicación se encuentra en un mal estado y está fallando, esta fijación puede hacer que todas las solicitudes tengan un error hasta que se corrija la situación, mientras que si limita cuántas tienen la posibilidad de equilibrarse con un nuevo servidor .
dtauzell
No me he encontrado con un equilibrador de carga que funcione así. Un equilibrador de carga generalmente tiene un parámetro de "adherencia" que define si todas las solicitudes del cliente (determinadas por IP, por ejemplo) dentro de la sesión actual deben enrutarse a la misma cadena ascendente o distribuirse entre las cadenas ascendentes. La opción que sea útil depende de la aplicación que se está ejecutando en las aguas arriba.
Manuel
1

En parte, para evitar que un solo usuario acapare todas las ranuras de conexión. Sin límite, un cliente malintencionado o mal escrito podría hacerse cargo de todas las conexiones disponibles y conservarlas para siempre. Sin embargo, esta no es una gran mitigación para eso, en comparación con algo así como un límite de conexión por IP.

Principalmente equilibrio de carga, pero específicamente con respecto al mantenimiento. Si desea desconectar un servidor, colóquelo en 0 conexiones pero permita que las conexiones existentes finalicen por un período de tiempo. Poner un límite a la cantidad de solicitudes de keepalive significa que eventualmente los usuarios crearán con gracia una nueva conexión y serán trasladados a un nuevo servidor de fondo. Probablemente alguna forma de indicarle al servidor que debería dejar de aceptar keepalives por completo durante el proceso de drenaje sería aún mejor, pero que yo sepa, esa característica no existe.

Elliott
fuente