Publicado por & archivado en Linux, Servidores.

Si accedes a un mismo dominio a la vez desde dos o más equipos de la misma red y de repente dejan de cargar las páginas durante unos minutos y luego vuelve a funcionar solo, probablemente estés teniendo un problema con el reciclado del TIME-WAIT de los paquetes TCP.

 

El problema viene producido porque en muchas guías y software para optimización de servidores aconsejan activar el reciclado para reducir el número de paquetes en TIME-WAIT del servidor.

 

¿Por qué hay que reducir los paquetes en TIME-WAIT?

Bien, la teoría es que los paquetes en TIME-WAIT se quedan esperando (como su nombre indica), abiertos, durante aproximadamente un minuto, consumiendo los recursos del servidor.

 

El TIME-WAIT es parte del protocolo TCP (usado para las comunicaciones en Internet), que evita que segmentos retrasados de una conexión puedan ser aceptados por una conexión posterior de la misma IP y puerto de origen y destino. También sirve para asegurarse de que el destinatario del paquete ha cerrado la conexión.

 

Los servidores que sirven las páginas web tienen por defecto unos límites que pueden afectar a servidores con mucha carga, en concreto, los servidores GNU/Linux tienen asignados unos 30.000 puertos por defecto, como los paquetes TIME-WAIT ocupan una conexión porque se quedan abiertos durante un minuto, esto nos da un límite de unas 500 conexiones por segundo como máximo, así que si redujéramos el número de estos paquetes en espera el servidor podría atender más peticiones.

 

Un inciso aquí para explicar por qué las páginas web deberían tener la menor cantidad posible de elementos

Hay que tener en cuenta que una página web está hecha de múltiples elementos y que el servidor deberá abrir una conexión por cada uno, por tanto (queridos diseñadores de páginas), no es lo mismo una página que tiene el HTML, una hoja de estilos, un archivo javascript y digamos siete imágenes, que serían 10 elementos, que tener (como empieza a ser habitual), de 100 a 200 elementos por página, porque la diferencia es que el servidor pasaría de aceptar un máximo de 50 páginas cargadas por segundo con 10 elementos, a 5 con 100 elementos.

 

Claro que 5 páginas “sostenidas” por segundo no es moco de pavo, estaríamos hablando de unos 12 millones de páginas por mes, pero con menos elementos por página se pueden atender más conexiones de forma directamente proporcional.

 

También el uso de CDN (Content Delivery Network), para cargar los recursos de la página, mejora el escenario. Los que hacen páginas web saben lo que es, pero básicamente, en vez de cargar determinadas hojas de estilos, fuentes de letras o librerías desde nuestro propio servidor, podemos usar el servidor de otro, por ejemplo, en vez de cargar la librería jquery de nuestro servidor:

<script src="//midominio.com/js/jquery.min.js"></script>

 

La cargamos desde el servidor CDN de Google:

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

El archivo es el mismo, pero cuando se carga la página, en vez de salir de nuestro servidor es Google quién se lo entrega al navegador del usuario, ahorrándonos una conexión.

 

Inciso en el inciso para explicar otro motivo por el que las páginas deben tener pocos elementos.

 

El motivo es que los navegadores tienen un límite de elementos que cargan de una vez, normalmente de 6 a 10, así que si una página tiene 100 elementos el navegador tendrá que abrir 10 peticiones como mínimo, ralentizando el proceso de carga aun más.

 

Uno de estos días escribiré una entrada sobre esto, porque luego vienen las lamentaciones cuando el responsable del SEO nos dice que nuestra web da pena. El consejo que damos los consultores ante esto suele ser “haz la página otra vez, pero esta vez hazla bien”, y no, instalarle un caché al WordPress no sirve para nada, normalmente incluso va más lento, así que te lo puedes ahorrar.

 

En Prestashop y Magento funcionan los cachés “bien instalados”, por el tipo de contenidos, pero el problema de estos programas es de su arquitectura, está relacionado con la forma de programar los accesos a la base de datos mucho más que por el número de elementos (que también), pero bueno, también escribiré una entrada sobre esto uno de estos días.

 

Continuando con el TIME-WAIT

 

Siguiendo con el hilo de la cuestión, ahora que sabemos que los paquetes en TIME-WAIT limitan el número de conexiones posibles, podemos entender por qué algunos recomiendan activar el reciclado de los paquetes en este estado antes de que caduquen (antes del minuto que duran por defecto), ya que evidentemente esto reduciría su número, permitiendo un aumento de las conexiones que el servidor puede manejar.

 

Lástima que eso sea una mala idea.

 

En “The Linux kernel documentation” dice esto sobre el parámetro “net.ipv4.tcp_tw_recycle” (que sirve para activar el reciclado de paquetes en TIME-WAIT):

Enable fast recycling TIME-WAIT sockets. Default value is 0. It should not be changed without advice/request of technical experts.

“No se debe cambiar sin el consejo de expertos” dice, pero bueno, ya sabemos lo que pasa en Internet, que todo el mundo es experto ¿Verdad?

 

¿Entonces que hago con el net.ipv4.tcp_tw_recycle?

 

Pues ya lo has leído, no lo toques si no sabes lo que estás haciendo, porque todo el mundo navega hoy en día detrás de un NAT.

 

Hay una forma rápida de saber si activar el net.ipv4.tcp_tw_recycle en el kernel nos habría producido alguna mejora. Ejecuta esto, como root o con sudo, en un terminal de tu servidor web (si no tienes acceso de consola como root a tu servidor, es algo que no puedes verificar):

netstat -nat | awk '{print $6}' | sort | uniq -c | sort -n

 

El resultado será algo como esto:

 1 established
 1 Foreign
 3 FIN_WAIT1
 14 LISTEN
 26 ESTABLISHED
 41 TIME_WAIT

 

Si el valor de la última línea está lejos de 30.000 (lo habitual son como mucho unos cientos), activar el reciclado de estos paquetes no aportará ningún beneficio y sólo tendrás problemas.

 

Si el valor es muy alto, entonces puedes buscar otras soluciones mejores, yo pondría un sistema con balanceo de carga o contrataría con Cloudflare, pero siempre puedes aumentar el número de puertos disponibles. Para ver los que tienes, prueba con:

sysctl net.ipv4.ip_local_port_range

 

Normalmente el valor por defecto incluye 28.232 puertos, del 32.768 al 61.000:

net.ipv4.ip_local_port_range = 32768 61000

 

Aunque esto se puede aumentar fácilmente añadiendo el nuevo rango en /etc/sysctl.conf, por ejemplo:

net.ipv4.ip_local_port_range = 2000 65535

 

Luego recarga los datos al kernel con:

sysctl -p

 

Esto aumentaría los puertos a 63.535, que te permitiría manejar más de mil conexiones por segundo.

 

Pero recuerda, todo esto es innecesario si el número de paquetes en TIME-WAIT es bajo (menos de 1000 es muy aceptable). Si tienes decenas de miles de estos paquetes es que tienes un tráfico del demonio, y probablemente grandes ingresos, y probablemente todo lo que digo aquí ya lo sabes, pero si tu servidor va lento y cuando miras tienes un número reducido de paquetes en espera, tu problema de velocidad está producido por otro motivo, y como ya se está convirtiendo en epidemia, apostaría a que es la base de datos. Si, acertaste, voy a escribir también una entrada sobre esto.

 

Resumiendo

Optimizar los servidores es bueno, de eso vivimos en Intervia (entre otras cosas), pero nada va a mejorar tanto el funcionamiento de tu web como hacer bien la programación, y aunque no lo parezca, te saldrá muchísimo más barato que gastar una fortuna en un servidor de alto rendimiento, tanto más barato, que con muchas webs el ahorro hace que la programación te salga gratis a poco que tengas tráfico.

 

 

Deja un comentario

Tu dirección de correo electrónico no será publicada.