41 votes

Comment réduire le nombre de sockets en TIME_WAIT?

Ubuntu Server 10.04.1 x86

J'ai une machine avec un service HTTP FCGI derrière nginx, qui sert beaucoup de petites requêtes HTTP à de nombreux clients différents. (Environ 230 requêtes par seconde aux heures de pointe, la taille moyenne de réponse avec les en-têtes est de 650 octets, plusieurs millions de clients différents par jour.)

En conséquence, j'ai beaucoup de sockets en TIME_WAIT (le graphique est capturé avec les paramètres TCP ci-dessous) :

TIME_WAIT

J'aimerais réduire le nombre de sockets.

Que puis-je faire à part cela ?

$ 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

Mise à jour : quelques détails sur la disposition réelle du service sur la machine :

client -----socket-TCP--> nginx (répartiteur de charge proxy inverse) 
       -----socket-TCP--> nginx (travailleur) 
       --socket-de-domaine--> logiciel fcgi
                          --socket-TCP-persistant--> Redis
                          --socket-TCP-persistant--> MySQL (autre machine)

Je devrais probablement également passer la connexion répartiteur de charge -> travailleur à des sockets de domaine, mais le problème des sockets TIME_WAIT persisterait - je prévois d'ajouter un deuxième travailleur sur une machine distincte bientôt. Ne pourrais pas utiliser de sockets de domaine dans ce cas.

33voto

Kyle Brandt Points 81077

Une chose que vous devriez faire pour commencer est de corriger le net.ipv4.tcp_fin_timeout=1. C'est beaucoup trop bas, vous ne devriez probablement pas descendre en dessous de 30.

Étant donné que ceci est derrière nginx. Est-ce que cela signifie que nginx agit comme un proxy inverse? Si tel est le cas, alors vos connexions sont multipliées par 2 (une vers le client, une vers vos serveurs Web). Savez-vous à quelle extrémité appartiennent ces sockets?

Mise à jour:
fin_timeout est la durée pendant laquelle ils restent en FIN-WAIT-2 (De networking/ip-sysctl.txt dans la documentation du noyau):

tcp_fin_timeout - INTEGER
        Temps de maintien du socket dans l'état FIN-WAIT-2, s'il a été fermé
        de notre côté. L'autre partie peut être déconnectée et ne pas fermer son côté,
        ou même être morte de manière inattendue. La valeur par défaut est de 60 sec.
        La valeur habituelle utilisée dans la version 2.2 était de 180 secondes, vous pouvez la restaurer,
        mais rappelez-vous que si votre machine est même un serveur WEB sous-chargé,
        vous risquez de déborder de mémoire avec des tonnes de sockets morts,
        les sockets FIN-WAIT-2 sont moins dangereux que les FIN-WAIT-1,
        parce qu'ils consomment au maximum 1,5K de mémoire, mais ils ont tendance
        à vivre plus longtemps. Cf. tcp_max_orphans.

Je pense que vous devrez peut-être laisser Linux maintenir le nombre de sockets en TIME_WAIT à ce qui semble peut-être être une limite de 32k sur eux et c'est là que Linux les recycle. Ce 32k est évoqué dans ce lien:

Aussi, je trouve le /proc/sys/net/ipv4/tcp_max_tw_buckets déroutant. Bien que la valeur par défaut soit de 180000, je constate une perturbation TCP lorsque j'ai 32K sockets TIME_WAIT sur mon système, quelle que soit la valeur max tw buckets.

Ce lien suggère également que l'état TIME_WAIT est de 60 secondes et ne peut pas être ajusté via proc.

Fait amusant aléatoire:
Vous pouvez voir les minuteries sur les timewait avec netstat pour chaque socket avec netstat -on | grep TIME_WAIT | less

Réutilisation Vs Recyclage:
Ce sont assez intéressants, il semble que la réutilisation active la réutilisation des sockets TIME_WAIT, et le recyclage les met en mode TURBO:

tcp_tw_recycle - BOOLEAN
        Activer le recyclage rapide des sockets en TIME-WAIT. La valeur par défaut est 0.
        Cela ne devrait pas être modifié sans l'avis/demande d'experts
        techniques.

tcp_tw_reuse - BOOLEAN
        Autoriser la réutilisation des sockets TIME-WAIT pour de nouvelles connexions lorsque c'est
        sûr d'un point de vue protocole. La valeur par défaut est 0.
        Cela ne devrait pas être modifié sans l'avis/demande d'experts
        techniques.

Je ne recommanderais pas d'utiliser net.ipv4.tcp_tw_recycle car cela pose des problèmes avec les clients NAT.

Peut-être pourriez-vous essayer de ne pas avoir les deux activés et voir quel effet cela a (Essayez un à la fois et voyez comment ils fonctionnent individuellement)? J'utiliserais netstat -n | grep TIME_WAIT | wc -l pour obtenir une rétroaction plus rapide que Munin.

3voto

andrew pate Points 251

Tcp_tw_reuse est relativement sûr car il permet aux connexions TIME_WAIT d'être réutilisées.

De plus, vous pourriez exécuter plus de services écoutant sur des ports différents derrière votre répartiteur de charge si le manque de ports est un problème.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X