Wie reduziert man die Anzahl der Sockets in TIME_WAIT?

36

Ubuntu Server 10.04.1 x86

Ich habe eine Maschine mit einem FCGI-HTTP-Dienst hinter nginx, der viele kleine HTTP-Anforderungen an viele verschiedene Clients bedient. (Ungefähr 230 Anfragen pro Sekunde in den Stoßzeiten, durchschnittliche Antwortgröße mit Headern beträgt 650 Bytes, mehrere Millionen verschiedener Clients pro Tag.)

Als Ergebnis habe ich viele Sockets, die in TIME_WAIT hängen (Grafik wird mit den folgenden TCP-Einstellungen erfasst):

ZEIT WARTET

Ich möchte die Anzahl der Steckdosen reduzieren.

Was kann ich sonst noch tun?

$ 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

Update: Einige Details zum tatsächlichen Service-Layout der Maschine:

Client ----- TCP-Socket -> Nginx (Load Balancer Reverse Proxy) 
       ----- TCP-Socket -> Nginx (Arbeiter) 
       --domain-socket -> fcgi-software
                          --single-persistent-TCP-socket -> Redis
                          --single-persistent-TCP-socket -> MySQL (andere Maschine)

Ich sollte wahrscheinlich Load-Balancer -> Worker-Verbindung auch auf Domain-Sockets umstellen, aber das Problem mit TIME_WAIT-Sockets würde bestehen bleiben. Ich plane, bald einen zweiten Worker auf einem separaten Computer hinzuzufügen. In diesem Fall können keine Domain-Sockets verwendet werden.

Alexander Gladysh
quelle
Es scheint, dass Munin schamlos lügt. Siehe Kommentare zur Antwort von Kyle. Schauen Sie sich das jetzt an.
Alexander Gladysh
1
Hat
Alexander Gladysh
Nun sieht es so aus, als würde Munin nicht lügen, sondern ich schaue auf die falsche Handlung ...
Alexander Gladysh

Antworten:

28

Eine Sache, die Sie tun sollten, um zu beginnen, ist, das Problem zu beheben net.ipv4.tcp_fin_timeout=1. Das ist viel zu niedrig, Sie sollten wahrscheinlich nicht viel niedriger als 30 nehmen.

Da steht das hinter nginx. Bedeutet das, dass Nginx als Reverse Proxy fungiert? In diesem Fall bestehen zwei Verbindungen (eine zum Client und eine zu Ihren Webservern). Wissen Sie, zu welchem ​​Ende diese Steckdosen gehören?

Update:
fin_timeout gibt an, wie lange sie in FIN-WAIT-2 bleiben (Ab networking/ip-sysctl.txtin der Kerneldokumentation ):

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.

Ich denke, Sie müssen Linux vielleicht nur die TIME_WAIT-Socket-Nummer mit einer Größe von 32 KB vergleichen lassen, und hier recycelt Linux sie. Auf diese 32k wird in diesem Link angespielt :

Außerdem finde ich das / proc / sys / net / ipv4 / tcp_max_tw_buckets verwirrend. Obwohl die Standardeinstellung auf 180000 festgelegt ist, wird eine TCP-Unterbrechung angezeigt, wenn auf meinem System 32K TIME_WAIT-Sockets vorhanden sind, unabhängig von den maximal zwei Buckets.

Dieser Link weist auch darauf hin, dass der TIME_WAIT-Status 60 Sekunden beträgt und nicht über proc eingestellt werden kann.

Zufällige lustige Tatsache:
Sie können die Timer auf dem timeWait mit netstat für jeden Sockel mit sehennetstat -on | grep TIME_WAIT | less

Wiederverwenden Vs Recyceln:
Diese sind interessant, da sie die Wiederverwendung von time_Wait-Sockets ermöglichen, und recycle versetzt sie in den TURBO-Modus:

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.

Ich würde die Verwendung von net.ipv4.tcp_tw_recycle nicht empfehlen, da dies Probleme mit NAT-Clients verursacht .

Vielleicht können Sie versuchen, nicht beide Geräte einzuschalten, um zu sehen, welche Auswirkungen dies hat. Ich würde netstat -n | grep TIME_WAIT | wc -lfür eine schnellere Rückmeldung als Munin verwenden.

Kyle Brandt
quelle
1
@Kyle: welchen wert net.ipv4.tcp_fin_timeoutwürdest du empfehlen?
Alexander Gladysh
1
@Kyle: Client --TCP-Socket -> Nginx (Load Balancer Reverse Proxy) --TCP-Socket -> Nginx (Worker) --Domain-Socket -> FCGI-Software
Alexander Gladysh
2
Ich würde sagen 30oder vielleicht 20. Probieren Sie es aus und sehen Sie. Du hast eine Menge Last, also macht eine Menge TIME_WAIT Sinn.
Kyle Brandt
1
@Kyle: Entschuldigung für eine blöde Frage (ich bin hier leider auf einem Cargo-Kult-Level), aber was genau soll ich erwarten, wenn ich net.ipv4.tcp_fin_timeoutvon 1zu wechsle 20?
Alexander Gladysh
4
Oh, hier ist ein schönes Motto: netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c. Also, @Alex, wenn Munin es nicht mag, probieren Sie einfach aus, wie er diese Statistiken überwacht. Vielleicht ist das einzige Problem, dass Munin Ihnen schlechte Daten gibt :-)
Kyle Brandt
1

tcp_tw_reuse ist relativ sicher, da TIME_WAIT-Verbindungen wiederverwendet werden können.

Sie können auch mehr Dienste ausführen, die auf verschiedenen Ports hinter Ihrem Load-Balancer empfangsbereit sind, wenn das Problem besteht, dass nicht genügend Ports zur Verfügung stehen.

Andrew Pate
quelle