41 votos

¿Cómo reducir el número de enchufes en TIME_WAIT?

Ubuntu Server 10.04.1 x86

Tengo una máquina con un servicio HTTP FCGI detrás de nginx, que sirve un montón de pequeñas peticiones HTTP a un montón de clientes diferentes. (Unas 230 peticiones por segundo en las horas punta, el tamaño medio de la respuesta con cabeceras es de 650 bytes, varios millones de clientes diferentes al día).

Como resultado, tengo un montón de sockets, colgando en TIME_WAIT (el gráfico se captura con la configuración de TCP abajo):

TIME_WAIT

Me gustaría reducir el número de enchufes.

¿Qué puedo hacer además de esto?

$ cat /proc/sys/net/ipv4/tcp\_fin\_timeout
1
$ cat /proc/sys/net/ipv4/tcp\_tw\_recycle
1
$ cat /proc/sys/net/ipv4/tcp\_tw\_reuse
1

Actualización: algunos detalles sobre la disposición real del servicio en la máquina:

client -----TCP-socket--> nginx (load balancer reverse proxy) 
       -----TCP-socket--> nginx (worker) 
       --domain-socket--> fcgi-software
                          --single-persistent-TCP-socket--> Redis
                          --single-persistent-TCP-socket--> MySQL (other machine)

Probablemente debería cambiar la conexión del balanceador de carga --> trabajador a sockets de dominio también, pero el problema de los sockets TIME_WAIT permanecería - planeo añadir un segundo trabajador en una máquina separada pronto. No podré usar los sockets de dominio en ese caso.

33voto

Kyle Brandt Puntos 50907

Una cosa que deberías hacer para empezar es arreglar el net.ipv4.tcp_fin_timeout=1 . Eso es demasiado bajo, probablemente no deberías tomar mucho menos de 30.

Ya que esto está detrás de nginx. ¿Significa eso que nginx está actuando como un proxy inverso? Si ese es el caso, entonces sus conexiones son 2x (una al cliente, otra a sus servidores web). ¿Sabes a qué extremo pertenecen estos sockets?

Actualización:
fin_timeout es el tiempo que permanecen en FIN-WAIT-2 (De networking/ip-sysctl.txt en la documentación del núcleo):

tcp_fin_timeout - INTEGER
        Time to hold socket in state FIN-WAIT-2, if it was closed
        by our side. Peer can be broken and never close its side,
        or even died unexpectedly. Default value is 60sec.
        Usual value used in 2.2 was 180 seconds, you may restore
        it, but remember that if your machine is even underloaded WEB server,
        you risk to overflow memory with kilotons of dead sockets,
        FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1,
        because they eat maximum 1.5K of memory, but they tend
        to live longer. Cf. tcp_max_orphans.

Creo que tal vez sólo tienes que dejar que Linux mantenga el número de socket TIME_WAIT contra lo que parece ser tal vez 32k cap en ellos y esto es donde Linux los recicla. Este 32k es aludido en esto enlace :

Además, encuentro el archivo /proc/sys/net/ipv4/tcp_max_tw_buckets es confuso. Aunque el valor por defecto se establece en 180000, veo una interrupción TCP cuando tengo 32K sockets TIME_WAIT en mi en mi sistema, sin importar el valor máximo de tw buckets.

Este enlace también sugiere que el estado TIME_WAIT es de 60 segundos y no puede ser ajustado vía proc.

Dato curioso al azar:
Puedes ver los temporizadores en el timewait con netstat para cada socket con netstat -on | grep TIME_WAIT | less

Reutilizar frente a reciclar:
Estos son un poco interesantes, se lee como reuse habilitar la reutilización de sockets time_Wait, y recycle lo pone en modo TURBO:

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

tcp_tw_reuse - BOOLEAN
        Allow to reuse TIME-WAIT sockets for new connections when it is
        safe from protocol viewpoint. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

Yo no recomendaría el uso de net.ipv4.tcp_tw_recycle ya que causa problemas con los clientes NAT .

Tal vez podrías probar a no tener los dos encendidos y ver qué efecto tiene (probar uno a la vez y ver cómo funcionan por separado). Yo usaría netstat -n | grep TIME_WAIT | wc -l para una respuesta más rápida que Munin.

3voto

andrew pate Puntos 26

Tcp_tw_reuse es relativamente seguro ya que permite reutilizar las conexiones TIME_WAIT.

También puedes ejecutar más servicios escuchando en diferentes puertos detrás de tu balanceador de carga si quedarte sin puertos es un problema.

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