BLOG | NGINX

Conexiones HTTP Keepalive y rendimiento web

NGINX - Parte de F5 - horizontal, negro, tipo RGB
Miniatura de Owen Garrett
Owen Garrett
Publicado el 14 de marzo de 2014

¿Alguna vez ha evaluado un servidor en el laboratorio y luego lo ha implementado para tráfico real, solo para descubrir que no puede lograr nada cercano al rendimiento de referencia? La utilización de la CPU es baja y hay muchos recursos libres, pero los clientes se quejan de tiempos de respuesta lentos y no saben cómo obtener una mejor utilización del servidor.

Lo que estás observando es un efecto de lo que podemos llamar “trabajo pesado HTTP”. En esta publicación de blog, investigamos cómo funciona HTTP y cómo los servidores HTTP comunes procesan las transacciones HTTP. Observamos algunos de los problemas de rendimiento que pueden ocurrir y vemos cómo el modelo impulsado por eventos de NGINX lo convierte en un proxy de aceleración muy eficaz para estos servidores HTTP. Con NGINX, puedes transformar tu rendimiento en el mundo real para que vuelva al nivel de tus puntos de referencia locales.

Para obtener sugerencias sobre cómo optimizar Linux y NGINX para mejorar la velocidad y la escalabilidad de sus aplicações, consulte Optimización de NGINX para mejorar el rendimiento en nuestro blog.

Introducción a las conexiones HTTP y Keepalive

Las conexiones HTTP keepalive son una característica de rendimiento necesaria que reduce la latencia y permite que las páginas web se carguen más rápido.

HTTP es un protocolo simple basado en texto. Si no lo ha hecho antes, observe la salida de una herramienta de depuración HTTP, como la de su navegador web, y verifique la estructura estándar de solicitud y respuesta:

En su implementación más simple, un cliente HTTP crea una nueva conexión TCP al servidor de destino, escribe la solicitud y recibe la respuesta. Luego, el servidor cierra la conexión TCP para liberar recursos.

Este modo de funcionamiento puede resultar muy ineficiente, especialmente para páginas web complejas con una gran cantidad de elementos o cuando los enlaces de red son lentos. La creación de una nueva conexión TCP requiere un «apretón de manos de tres vías» y su desconexión también implica un procedimiento de apagado de dos vías. Crear y cerrar repetidamente conexiones TCP, una para cada mensaje, es similar a colgar y volver a marcar después de que cada persona habla en una conversación telefónica.

HTTP utiliza un mecanismo llamado conexiones keepalive para mantener abierta la conexión TCP entre el cliente y el servidor después de que se haya completado una transacción HTTP. Si el cliente necesita realizar otra transacción HTTP, puede utilizar la conexión keepalive inactiva en lugar de crear una nueva conexión TCP.

Los clientes generalmente abren varias conexiones TCP simultáneas a un servidor y realizan transacciones keepalive en todas ellas. Estas conexiones se mantienen abiertas hasta que el cliente o el servidor deciden que ya no son necesarias, generalmente como resultado de un tiempo de espera inactivo.

Los navegadores web modernos generalmente abren entre 6 y 8 conexiones keepalive y las mantienen abiertas durante varios minutos antes de expirar. Los servidores web pueden configurarse para cronometrar estas conexiones y cerrarlas antes.

¿Cuál es el efecto de Keepalive en el servidor HTTP?

Si muchos clientes utilizan keepalives HTTP y el servidor web tiene un límite de concurrencia o un problema de escalabilidad, entonces el rendimiento se desploma una vez que se alcanza ese límite.

El enfoque anterior está diseñado para brindar el mejor rendimiento posible para un cliente individual. Desafortunadamente, en un escenario similar a la " tragedia de los comunes ", si todos los clientes operan de esta manera, puede tener un efecto perjudicial en el rendimiento de muchos servidores y aplicações web comunes.

La razón es que muchos servidores tienen un límite de concurrencia fijo. Por ejemplo, en configuraciones comunes, el servidor HTTP Apache solo puede procesar un número limitado de conexiones TCP simultáneas: 150 con el módulo de multiprocesamiento de trabajador (MPM) y 256 con el MPM prefork . Cada conexión HTTP keepalive inactiva consume uno de estos espacios de concurrencia y, una vez que todos los espacios están ocupados, el servidor no puede aceptar más conexiones HTTP.

La sabiduría convencional dice que se debe desactivar el keepalive en el servidor web o limitarlo a una vida útil muy corta. Proporcionan un vector muy simple para los ataques de denegación de servicio SlowHTTPTest y Slowloris (para una solución rápida, consulte Protección contra la denegación de servicio Keep-Dead en serverfault.com).

Además, estos servidores web y de aplicação normalmente asignan un hilo o proceso del sistema operativo para cada conexión. Una conexión TCP es un objeto de sistema operativo muy liviano, pero un hilo o proceso es muy pesado. Los subprocesos y procesos requieren memoria, deben ser administrados activamente por el sistema operativo y el «cambio de contexto» entre subprocesos o procesos consume CPU. Asignar a cada conexión su propio hilo o proceso es enormemente ineficiente.

La gran cantidad de conexiones de cliente simultáneas y la asignación de un hilo o proceso a cada conexión produce el fenómeno conocido como “HTTP heavy lifting”, donde se requiere un esfuerzo desproporcionadamente grande para procesar una transacción HTTP liviana.

¿Qué significa esto en la práctica?

No se necesitan muchos clientes para agotar el límite de concurrencia en muchos servidores web y de aplicação contemporáneos.

Si un cliente abre 8 conexiones TCP y mantiene cada una de ellas activa durante 15 segundos después del último uso, el cliente consume 8 espacios de concurrencia durante 15 segundos. Si los clientes llegan a su sitio web a una velocidad de 1 por segundo, 120 ranuras de concurrencia estarán ocupadas continuamente por conexiones keepalive inactivas. Si la velocidad es de 2 clientes por segundo, se ocupan 240 ranuras de concurrencia. Una vez que se agotan los espacios, los nuevos clientes no pueden conectarse hasta que se agote el tiempo de conexión de las conexiones existentes.

Esto puede generar niveles de servicio muy desiguales. Los clientes que adquieran con éxito una conexión keepalive podrán navegar por su servicio a voluntad. Los clientes que intentan conectarse cuando todas las ranuras de concurrencia están ocupadas quedan bloqueados y deben esperar en una cola.

¿Por qué no se ven estos efectos durante las pruebas comparativas?

Estos problemas sólo se manifiestan en redes lentas con muchos clientes. No aparecen cuando se realiza una evaluación comparativa con un solo cliente a través de una red local rápida.

Hay un par de razones por las cuales es posible que no veas estos efectos en un punto de referencia.

  • Si no habilita keepalives durante la prueba comparativa, el cliente crea una nueva conexión TCP para cada transacción (y la conexión se interrumpe después de que se completa la transacción). Dado que lo más probable es que estés ejecutando la prueba comparativa en una red local rápida, la prueba comparativa tiene éxito y no ves los problemas de rendimiento creados por no usar keepalives.
  • Si habilita keepalives , lo más probable es que pueda ejecutar menos conexiones simultáneas que el límite de su servidor y su cliente de referencia sature cada conexión (la use repetidamente), lo que llevará a su servidor a su capacidad máxima. Sin embargo, esto no se parece al perfil del mundo real para las conexiones.

Tenga en cuenta que la mayoría de las herramientas de referencia solo informan sobre transacciones exitosas. Es posible que las conexiones que se detienen debido al agotamiento de recursos no se informen o parezcan ser solo una pequeña fracción de las conexiones exitosas. Esto oculta la verdadera naturaleza del problema con el tráfico del mundo real.

¿Qué tan común es el problema?

Cualquier servidor web o de aplicação basado en subprocesos o procesos es vulnerable a limitaciones de concurrencia.

Este problema es inherente a cualquier plataforma web o de aplicação que asigna un hilo o proceso a cada conexión. No es fácil de detectar en un entorno de referencia optimizado, pero se manifiesta como un rendimiento deficiente y un uso excesivo de la CPU en un entorno del mundo real.

Hay varias medidas que puedes tomar para solucionar este problema:

  • Aumentar el número de subprocesos o procesos: esta es una medida a muy corto plazo. Los subprocesos y procesos son objetos pesados del sistema operativo y generan una sobrecarga de administración que aumenta rápidamente a medida que se generan más y más.
  • Deshabilitar o limitar el uso de keepalives HTTP: esto pospone el límite de concurrencia, pero da como resultado un rendimiento mucho peor para cada cliente.
  • Utilice el procesamiento keepalive especializado: el servidor HTTP Apache (servidor web) tiene un MPM de eventos relativamente nuevo que mueve las conexiones entre subprocesos de trabajo y un subproceso de eventos dedicado cuando se mueven entre estados "activos" e "inactivos" de keepalive. Esta puede ser una opción si los otros módulos que utiliza admiten este MPM; tenga en cuenta que las conexiones SSL/TLS aún se procesan completamente en subprocesos dedicados.
  • Utilice un modelo de procesamiento más eficiente: la medida más simple y efectiva que puede tomar es colocar un proxy HTTP eficiente frente a sus servidores web o de aplicação . Un proxy controlado por eventos como NGINX no tiene las limitaciones de concurrencia descritas anteriormente. Se ríe de las conexiones lentas y de los keepalives inactivos. Además, traduce de manera efectiva las conexiones lentas del lado del cliente con múltiples conexiones keepalive inactivas en conexiones rápidas, locales y altamente eficientes de estilo benchmark que extraen el mejor rendimiento posible de sus servidores web y de aplicação .

Utilice NGINX como proxy HTTP acelerador

NGINX utiliza una arquitectura diferente que no sufre los problemas de concurrencia descritos anteriormente. Transforma conexiones lentas de clientes en conexiones optimizadas similares a las de referencia para extraer el mejor rendimiento de sus servidores.

NGINX utiliza un modelo impulsado por eventos altamente eficiente para administrar las conexiones.

Cada proceso NGINX puede manejar múltiples conexiones al mismo tiempo. Cuando se acepta una nueva conexión, la sobrecarga es muy baja (consiste en un nuevo descriptor de archivo y un nuevo evento para sondear), a diferencia del modelo por proceso o por hilo descrito anteriormente. NGINX tiene un bucle de eventos muy efectivo:

Esto permite que cada proceso NGINX escale fácilmente a decenas, miles o cientos de miles de conexiones simultáneamente.

Luego, NGINX envía las solicitudes al servidor ascendente, utilizando un grupo local de conexiones keepalive. No incurre en la sobrecarga de abrir y cerrar conexiones TCP, y las pilas TCP se adaptan rápidamente al tamaño de ventana óptimo y a los parámetros de reintento. Escribir solicitudes y leer respuestas es mucho más rápido en la red local optimizada:

El efecto neto es que el servidor ascendente se encuentra hablando con un solo cliente local (NGINX) a través de una red rápida, y es un cliente que hace un uso óptimo de las conexiones HTTP keepalive para minimizar la configuración de la conexión sin mantener las conexiones abiertas innecesariamente. Esto devuelve al servidor a su entorno óptimo, similar al de referencia.

Con NGINX actuando como proxy HTTP, verás:

  • Mejor utilización de los recursos existentes. Sus servidores web y de aplicação pueden procesar más transacciones por segundo porque ya no realizan el pesado trabajo de HTTP.
  • Tasas de error reducidas. Los tiempos de espera de HTTP son mucho menos probables porque NGINX actúa como un programador central para todos los clientes.
  • Mejor rendimiento para el usuario final. Los servidores funcionan de manera más eficiente y las conexiones de servicio son más rápidas.

Otras formas en que NGINX puede acelerar los servicios

Eliminar la carga del trabajo pesado de HTTP es solo una de las medidas de transformación del rendimiento que NGINX puede aportar a su infraestructura de aplicaciones sobrecargada.

La función de almacenamiento en caché HTTP de NGINX puede almacenar en caché las respuestas de los servidores ascendentes, siguiendo la semántica de caché estándar para controlar qué se almacena en caché y durante cuánto tiempo. Si varios clientes solicitan el mismo recurso, NGINX puede responder desde su caché y no sobrecargar los servidores ascendentes con solicitudes duplicadas.

NGINX también puede descargar otras operaciones del servidor ascendente. Puede descargar las operaciones de compresión de datos para reducir el uso del ancho de banda, centralizar el cifrado y descifrado SSL/TLS , realizar la autenticación inicial del cliente (por ejemplo, con autenticación básica HTTP , subsolicitudes a servidores de autenticación externos y tokens web JSON ) y aplicar todo tipo de reglas para limitar la velocidad del tráfico cuando sea necesario.

No es el típico balanceador de carga o ADC

Por último, no olvide que, a diferencia de otros proxies de aceleración, balanceadores de carga o controladores de entrega de aplicação (ADC), NGINX también es un servidor web completo . Puede utilizar NGINX para servir contenido estático , reenviar tráfico a servidores de aplicação para Java, PHP, Python, Ruby y otros lenguajes, entregar contenido multimedia (audio y video) , integrarse con sistemas de autenticación y seguridad, e incluso responder a transacciones directamente utilizando reglas integradas en la configuración de NGINX.

Sin limitaciones de rendimiento integradas, NGINX y NGINX Plus aprovechan al máximo el hardware en el que lo implementa, ahora y en el futuro.

Para probar NGINX Plus, comience hoy su prueba gratuita de 30 días o contáctenos para analizar sus casos de uso .


"Esta publicación de blog puede hacer referencia a productos que ya no están disponibles o que ya no reciben soporte. Para obtener la información más actualizada sobre los productos y soluciones F5 NGINX disponibles, explore nuestra familia de productos NGINX . NGINX ahora es parte de F5. Todos los enlaces anteriores de NGINX.com redirigirán a contenido similar de NGINX en F5.com.