1 votos

Golpeando el Agotamiento Efímero de Puertos TCP

Ejecutamos un sitio web con mucho tráfico. En los últimos días, varios clientes se han quejado de tiempos de inactividad intermitentes que no podemos reproducir. Tenemos varios servidores web designados para recibir tráfico de nuestro balanceador de carga, y al investigar me di cuenta de que todos los servidores estaban perdiendo más de 20 conexiones por segundo. Una muestra de conexiones de un servidor se veía así:

  38452 TIME_WAIT
   7815 ESTABLISHED
    570 FIN_WAIT2
    105 FIN_WAIT1
    101 LAST_ACK
     36 SYN_RECV
     25 CLOSING
      4 SYN_SENT
      2 CLOSE_WAIT
      1 Foreign

Nuestro rango de puertos configurado está actualmente establecido en 15000 61000 en todos los servidores. Parecería, entonces, que todos los puertos posibles deben estar agotados ya que el número de conexiones establecidas o esperando cerrarse es igual a 46267.

Mientras investigamos el tráfico, ¿qué deberíamos hacer con las conexiones perdidas? ¿Sería prudente aumentar nuestro rango de puertos? ¿Disminuir la cantidad de tiempo que esperan las conexiones para cerrarse? ¿Ambas cosas? ¿Hacer alguna de ellas tendría alguna consecuencia negativa potencial?

3voto

Jakov Sosic Puntos 1922

Hay un par de formas en las que puedes abordar este problema.

La forma más fácil es aumentar el rango efímero, pero ya hiciste un poco esto y obviamente hay límites en cuánto puedes avanzar con esta solución.

Otra solución sería el DNS de ronda-robin y agregar múltiples direcciones IP a los nodos de tu balanceador de carga. A veces esto no es fácilmente aplicable (necesitas esperar para obtener direcciones IP adicionales, esperar el período de propagación DNS, etc.)

Dos cosas que puedes hacer de inmediato mientras consideras otras soluciones a largo plazo serían reducir tus temporizadores TCP y activar tcp_reuse.

tcp_reuse es bastante seguro de usar en un balanceador de carga, y lo que hace es habilitar al kernel para reutilizar sockets en el estado TIME_WAIT para nuevas conexiones. Para activarlo, ejecuta en tu caja de Linux:

# sysctl -w net.ipv4.tcp_tw_reuse=1

Para que sea persistente al reiniciar:

# echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.d/net.ipv4.tcp_tw_reuse.conf

Otros parámetros de ajuste del kernel que pueden ayudar son:

  • net.core.somaxconn (tamaño de la cola de escucha)
  • net.ipv4.tcp_max_syn_backlog (número de solicitudes de conexión recordadas sin ACK)

También puedes reducir net.ipv4.tcp_fin_timeout a 1 o 2 (cuánto tiempo mantener los sockets en el estado FIN-WAIT-2 si tu host es el que cierra la conexión).

Espero que te ayude.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X