Ich weiß, dass es dazu einige SE-Fragen gibt, und ich glaube, ich habe so viele davon gelesen, wie es wichtig ist, bevor ich zu diesem Punkt komme.
Mit "serverseitig TIME_WAIT
" meine ich den Status eines serverseitigen Socket-Paares, dessen close () auf der Serverseite initiiert wurde.
Ich sehe oft diese Aussagen, die mir widersprechen:
- Serverseitig
TIME_WAIT
ist harmlos - Sie sollten Ihre Netzwerk-Apps so gestalten, dass Clients close () initiieren, damit der Client das trägt
TIME_WAIT
Der Grund, warum ich diesen Widerspruch finde, ist, dass TIME_WAIT
auf dem Client ein Problem auftreten kann - dem Client können die verfügbaren Ports ausgehen. Daher empfiehlt das oben Gesagte im Wesentlichen, die Last TIME_WAIT
auf die Client-Seite zu verlagern, wo es Probleme geben kann Serverseite, wo es kein Problem ist.
Die Clientseite TIME_WAIT
ist natürlich nur für eine begrenzte Anzahl von Anwendungsfällen ein Problem. Die meisten Client-Server-Lösungen umfassen einen Server und viele Clients. Clients haben normalerweise nicht genügend Verbindungsvolumen, um ein Problem zu verursachen, und selbst wenn dies der Fall ist, gibt es eine Reihe von Empfehlungen, die "vernünftig" sind ( Im Gegensatz zu SO_LINGER
0 Timeout oder Einmischung in tcp_tw sysctls) bekämpfen Sie die Clientseite, TIME_WAIT
indem Sie vermeiden, zu schnell zu viele Verbindungen herzustellen. Dies ist jedoch nicht immer möglich, beispielsweise für Anwendungsklassen wie:
- Überwachungssysteme
- Lastgeneratoren
- Proxies
Auf der anderen Seite verstehe ich nicht einmal, wie TIME_WAIT
hilfreich die Serverseite überhaupt ist. Der Grund TIME_WAIT
ist sogar da, weil es verhindert, dass abgestandene TCP
Fragmente in Streams injiziert werden , zu denen sie nicht mehr gehören. Für die Clientseite wird TIME_WAIT
dies erreicht, indem einfach unmöglich gemacht wird, eine Verbindung mit denselben ip:port
Paaren herzustellen, die diese veraltete Verbindung hätte haben können (die verwendeten Paare werden von gesperrt TIME_WAIT
). Auf der Serverseite kann dies jedoch nicht verhindert werden, da die lokale Adresse den akzeptierenden Port hat und immer gleich ist und der Server die Verbindung nicht einfach deshalb verweigern kann (AFAIK, ich habe nur den empirischen Beweis) Ein eingehender Peer würde dasselbe Adresspaar erstellen, das bereits in der Socket-Tabelle vorhanden ist.
Ich habe ein Programm geschrieben, das zeigt, dass serverseitiges TIME-WAIT ignoriert wird. Da der Test auf 127.0.0.1 durchgeführt wurde, muss der Kernel außerdem ein spezielles Bit haben, das sogar angibt, ob es sich um eine Server- oder eine Clientseite handelt (da sonst das Tupel dasselbe wäre).
Quelle: http://pastebin.com/5PWjkjEf , getestet auf Fedora 22, Standardnetzkonfiguration.
$ gcc -o rtest rtest.c -lpthread
$ ./rtest 44400 s # will do server-side close
Will initiate server close
... iterates ~20 times successfully
^C
$ ss -a|grep 44400
tcp TIME-WAIT 0 0 127.0.0.1:44400 127.0.0.1:44401
$ ./rtest 44500 c # will do client-side close
Will initiate client close
... runs once and then
connecting...
connect: Cannot assign requested address
Auf der Serverseite TIME_WAIT
konnten Verbindungen auf genau demselben Portpaar sofort und erfolgreich wiederhergestellt werden, und auf der Clientseite TIME-WAIT
schlug die zweite Iteration zu connect()
Recht fehl
Zusammenfassend ist die Frage zweifach:
- Tut serverseitig
TIME_WAIT
wirklich nichts und bleibt es einfach so, weil es dasRFC
erfordert? - Ist der Grund der Empfehlung, dass der Client close () initiiert, weil der Server
TIME_WAIT
unbrauchbar ist?
TIME_WAIT
.Antworten:
In TCP- Begriffen bedeutet Server-Seite hier den Host, dessen Socket sich im Status LISTEN befindet.
Mit RFC1122 kann der Socket im Status TIME-WAIT unter bestimmten Bedingungen eine neue Verbindung akzeptieren
Genaue Details zu den Bedingungen finden Sie im RFC1122 . Ich würde erwarten, dass es auch ein passendes passives OPEN am Socket geben muss (Socket im LISTEN-Status).
Active OPEN (clientseitiger Verbindungsaufruf) hat keine solche Ausnahme und muss einen Fehler ausgeben, wenn sich der Socket gemäß RFC793 in TIME-WAIT befindet .
Meine Vermutung für die Empfehlung auf dem Client (in TCP-Begriffen, dass der Host, der aktiv OPEN ausführt, dh eine Verbindung herstellt), der dem Schließen initiiert wurde, entspricht weitgehend Ihrer Empfehlung, dass im allgemeinen Fall die TIME-WAIT-Sockets auf mehr Hosts verteilt werden, für die es eine Fülle von Ressourcen gibt die Steckdosen. Im allgemeinen Fall senden Clients keine SYN, die TIME-WAIT-Sockets auf dem Server wiederverwenden würden. Ich bin damit einverstanden, dass die Anwendung einer solchen Empfehlung immer noch vom Anwendungsfall abhängt.
quelle
Dies ist wahrscheinlich das deutlichste Beispiel dafür, was TIME-WAIT tatsächlich tut und was noch wichtiger ist, warum es wichtig ist. Außerdem wird erläutert, warum Sie einige der Expertentipps auf Linux-Computern vermeiden sollten, um die Wartezeiten zu verkürzen.
quelle
Eine TCP-Sitzung wird durch das Tupple identifiziert (sourceIP, sourcePort, destIP, destPort). Daher funktioniert TIME_WAIT bei jeder TCP-Verbindung.
In Bezug auf die schließende Seite kann in einigen Szenarien das Schließen von der Client-Seite die TIME_WAIT-Sockets auf dem Server reduzieren, wodurch der Speicher geringfügig reduziert wird. In Fällen, in denen der Socket-Speicherplatz erschöpft sein kann (aufgrund einer kurzlebigen Portverarmung) (z. B. gierige Clients mit vielen Verbindungen zum selben Server), sollte dieses Problem auf jeder Seite gelöst werden.
quelle
TIME_WAIT
(ich habe die Frage mit diesen Informationen aktualisiert). @ Khushils Referenz behandelt serverseitigeTIME_WAIT
Fälle nicht detailliert genug.Mit einem unzuverlässigen Protokoll können Sie nie sicher sein, dass Sie die letzte Nachricht von Ihrem Peer-Gerät erhalten haben. Daher ist es gefährlich anzunehmen, dass Ihr Peer das Telefon ziemlich plötzlich aufgelegt hat. Es ist ein großer Nachteil des TCP-Protokolls, dass nur etwa 65000 Ports gleichzeitig geöffnet sein können. Der Weg, dies zu überwinden, besteht darin, zu einer Serverfarm zu wechseln, die mit der Last besser skaliert werden kann, als Portnummern schnell zu recyceln. Auf Client-Seite ist es sehr unwahrscheinlich, dass Ihnen die Ports ausgehen, wenn es sich um eine Basisarbeitsstation handelt.
quelle