Comment réduire le nombre de sockets dans TIME_WAIT?

36

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 à beaucoup de clients différents. (Environ 230 demandes par seconde aux heures de pointe, la taille moyenne des réponses 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, suspendus dans TIME_WAIT (le graphique est capturé avec les paramètres TCP ci-dessous):

TEMPS D'ATTENTE

J'aimerais réduire le nombre de prises.

Que puis-je faire à part ça?

$ 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 de service réelle sur la machine:

client ----- TCP-socket -> nginx (proxy inverse de l'équilibreur de charge) 
       ----- TCP-socket -> nginx (travailleur) 
       --domain-socket -> logiciel fcgi
                          --single-persistent-persistent-TCP-socket -> Redis
                          --single-persistent-persistent-TCP-socket -> MySQL (autre ordinateur)

Je devrais probablement basculer l'équilibreur de charge -> la connexion de l'ouvrier vers les sockets du domaine également, mais le problème des sockets TIME_WAIT resterait - je prévois d'ajouter bientôt un second ouvrier sur une machine séparée. Ne sera pas en mesure d'utiliser les sockets de domaine dans ce cas.

Alexander Gladysh
la source
Il semble que Munin ment sans vergogne. Voir les commentaires sur la réponse de Kyle. En regardant dans cela maintenant.
Alexander Gladysh
1
A créé une question à propos de Munin: serverfault.com/questions/212200/…
Alexander Gladysh
Maintenant, on dirait que Munin ne ment pas, mais je regarde plutôt le mauvais complot ...
Alexander Gladysh

Réponses:

28

Une chose à faire est de régler le problème net.ipv4.tcp_fin_timeout=1. C’est trop faible, vous ne devriez probablement pas prendre autant que 30.

Depuis c'est derrière nginx. Cela signifie-t-il que nginx agit en tant que proxy inverse? Si tel est le cas, vos connexions sont 2x (une vers client, une vers vos serveurs Web). Savez-vous à quelle extrémité appartiennent ces prises?

Mise à jour:
fin_timeout indique combien de temps ils restent dans FIN-WAIT-2 (à partir networking/ip-sysctl.txtde la documentation du noyau):

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.

Je pense que vous devez peut-être simplement laisser Linux garder le numéro de socket TIME_WAIT contre ce qui ressemble peut-être à une limite de 32k et c'est ici que Linux les recycle. Ce 32k est mentionné dans ce lien :

De plus, je trouve le fichier / proc / sys / net / ipv4 / tcp_max_tw_buckets déroutant. Bien que la valeur par défaut soit 180000, je vois une perturbation de TCP lorsque j'ai des sockets TIMEKIT 32K sur mon système, quels que soient les deux compartiments max.

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

Fait amusant:
vous pouvez voir les minuteries sur le temps d'attente avec netstat pour chaque socket avecnetstat -on | grep TIME_WAIT | less

Reuse Vs Recycle:
Celles-ci sont plutôt intéressantes, car elles se lisent comme si la réutilisation permettait la réutilisation des sockets time_Wait, et le recyclage le met en mode 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.

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-les un par un et voyez comment ils fonctionnent tout seuls)? Je voudrais utiliser netstat -n | grep TIME_WAIT | wc -lpour des commentaires plus rapides que Munin.

Kyle Brandt
la source
1
@Kyle: quelle valeur net.ipv4.tcp_fin_timeoutrecommanderiez-vous?
Alexander Gladysh
1
@Kyle: client --TCP-socket -> nginx (proxy inverse de l'équilibreur de charge) --TCP-socket -> nginx (worker) --domain-socket -> fcgi-software
Alexander Gladysh
2
Je dirais 30ou peut-être 20. Essayez et voyez. Vous avez beaucoup de charge, donc beaucoup de TIME_WAIT ont du sens.
Kyle Brandt
1
@Kyle: désolé pour une question stupide (je suis sur un niveau culte du cargo ici jusqu'à présent, malheureusement), mais que dois - je attendre exactement à voir quand je change net.ipv4.tcp_fin_timeoutde 1la 20?
Alexander Gladysh
4
Oh, voici une belle seule ligne: netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c. Alors, @Alex, si Munin n’apprécie pas, peut-être expliquer en détail comment il surveille ces statistiques. Le seul problème est peut-être que Munin vous donne de mauvaises données :-)
Kyle Brandt
1

tcp_tw_reuse est relativement sûr car il permet de réutiliser les connexions TIME_WAIT.

De plus, vous pouvez exécuter davantage de services d'écoute sur différents ports derrière votre équilibreur de charge si le nombre de ports disponibles est problématique.

Andrew Pate
la source