TCP-Socket-SYN-Warteschlange und Accept-Warteschlangen-Unterschiedsanalyse

TCP-Socket-SYN-Warteschlange und Accept-Warteschlangen-Unterschiedsanalyse

Zunächst müssen wir verstehen, dass ein TCP-Socket im Status „LISTENING“ zwei unabhängige Warteschlangen hat:

  • SYN-Warteschlange
  • Warteschlange akzeptieren

Diese beiden Begriffe werden manchmal auch „reqsk_queue“, „ACK-Backlog“, „Listen-Backlog“ oder sogar „TCP-Backlog“ genannt. In diesem Artikel verwenden wir jedoch die beiden oben genannten Begriffe, um Verwirrung zu vermeiden.

SYN-Warteschlange

Die SYN-Warteschlange speichert die Verbindungen, die SYN-Pakete empfangen (entspricht der Kernel-Codestruktur: struct inet_request_sock). Seine Aufgabe besteht darin, auf SYN+ACK-Pakete zu antworten und die Übertragung erneut durchzuführen, wenn keine ACK-Pakete empfangen werden, bis die Zeit abgelaufen ist. Unter Linux beträgt die Anzahl der erneuten Übertragungen:

$ sysctl net.ipv4.tcp_synack_retries

net.ipv4.tcp_synack_retries = 5

Die Beschreibung von tcp_synack_retries in der Dokumentation lautet wie folgt:

tcp_synack_retries - int
Die Anzahl der erneuten SYNACK-Übertragungen für eine passive TCP-Verbindung. Der Wert darf 255 nicht überschreiten.
Der Standardwert ist 5. Wenn die anfängliche RTO 1 Sekunde beträgt, beträgt die entsprechende letzte erneute Übertragung 31 Sekunden.
Das entsprechende letzte Timeout erfolgt 63 Sekunden später.

Nach dem Senden von SYN+ACK wartet die SYN-Warteschlange auf das vom Client gesendete ACK-Paket (also das letzte Paket des Drei-Wege-Handshakes). Wenn ein ACK-Paket empfangen wird, wird zuerst die entsprechende SYN-Warteschlange gefunden und dann werden die entsprechenden Daten in der entsprechenden SYN-Warteschlange überprüft, um festzustellen, ob eine Übereinstimmung vorliegt. Wenn eine Übereinstimmung vorliegt, entfernt der Kernel die mit der Verbindung verbundenen Daten aus der SYN-Warteschlange, erstellt eine vollständige Verbindung (entsprechend der Kernel-Codestruktur: struct inet_sock) und fügt diese Verbindung der Accept-Warteschlange hinzu.

Warteschlange akzeptieren

In der Akzeptanzwarteschlange werden hergestellte Verbindungen gespeichert, d. h. Verbindungen, die darauf warten, von der Anwendung auf höherer Ebene entfernt zu werden. Wenn der Prozess accept() aufruft, wird der Socket aus der Warteschlange genommen und an die Anwendung auf höherer Ebene übergeben.

Dies ist eine kurze Beschreibung, wie Linux SYN-Pakete verarbeitet. Übrigens, wenn für den Socket TCP_DEFER_ACCEPT und TCP_FASTOPEN aktiviert sind, ist die Arbeitsweise etwas anders und wird in diesem Artikel nicht vorgestellt.

Warteschlangengrößenlimit

Die Anwendung legt die maximale Größe der SYN-Warteschlange und der Accept-Warteschlange fest, indem sie den Systemaufruf listen(2) aufruft und den Backlog-Parameter übergibt. Wie unten gezeigt ist beispielsweise die maximale Größe der SYN-Warteschlange und der Accept-Warteschlange auf 1024 festgelegt:

hören(sfd, 1024)

Beachten Sie, dass in Kerneln vor 4.3 die Größe der SYN-Warteschlange auf andere Weise berechnet wird.

Die maximale Größe der SYN-Warteschlange wurde zuvor mit net.ipv4.tcp_max_syn_backlog konfiguriert, wird aber nicht mehr verwendet. Jetzt wird net.core.somaxconn verwendet, um die maximale Größe sowohl der SYN-Warteschlange als auch der Accept-Warteschlange darzustellen. Auf unseren Servern haben wir es auf 16 KB eingestellt:

$ sysctl net.core.somaxconn

net.core.somaxconn = 16384

Nachdem Sie die obigen Informationen kennen, fragen Sie sich vielleicht: Was ist die angemessene Warteschlangengröße? Was ist die angemessene Warteschlangengröße?

Die Antwort ist: es kommt darauf an. Für die meisten TCP-Dienste ist dies nicht so wichtig. Beispielsweise gab es vor der Go-Sprachversion 1.11 keine Methode zum Festlegen der Warteschlangengröße.

Es gibt jedoch einige berechtigte Gründe, die Warteschlangengröße zu erhöhen:

  • Wenn die Anzahl der Verbindungsaufbauanfragen sehr hoch ist, muss die SYN-Warteschlange möglicherweise sogar für einen Hochleistungsdienst größer eingestellt werden.
  • Die Größe der SYN-Warteschlange, also die Anzahl der Verbindungen, die auf ACK-Pakete warten. Das heißt, je länger die durchschnittliche Roundtrip-Zeit mit dem Client ist, desto mehr Verbindungen sammeln sich in der SYN-Warteschlange. In Szenarien, in denen die meisten Clients weit vom Server entfernt sind und die Roundtrip-Zeit beispielsweise mehr als einige hundert Millisekunden beträgt, kann die Warteschlangengröße größer eingestellt werden.
  • Wenn die Option TCP_DEFER_ACCEPT aktiviert ist, bewirkt dies, dass der Socket für längere Zeit im SYN-RECV-Zustand bleibt, wodurch sich die Zeit verlängert, die er in der SYN-Warteschlange verbleibt.

Allerdings kann es auch nachteilige Auswirkungen haben, wenn der Rückstand zu groß eingestellt wird: Jeder Slot in der SYN-Warteschlange benötigt etwas Speicher. Bei einem SYN-Flood-Angriff besteht keine Notwendigkeit, Ressourcen für diese angreifenden Pakete zu verschwenden. Die inet_request_sock-Struktur in der SYN-Warteschlange belegt unter dem 4.14-Kernel jeweils 256 Byte Speicher.

Wenn wir unter Linux den aktuellen Status der SYN-Warteschlange anzeigen möchten, können wir den Socket im SYN-RECV-Status mit dem Befehl ss abfragen. Beispielsweise zeigen die folgenden Ausführungsergebnisse an, dass sich derzeit 119 Elemente in der SYN-Warteschlange von Port 80 und 78 Elemente in der SYN-Warteschlange von Port 443 befinden.

$ ss -n state syn-recv sport = :80 | wc -l
119
$ ss -n state syn-recv sport = :443 | wc -l
78

Was passiert, wenn das Programm accept() nicht schnell genug aufruft? Sie können diese Daten auch über unser SystemTap-Skript beobachten: resq.stp

Was passiert, wenn das Programm accept() nicht schnell genug aufruft?

  • Nachfolgend empfangene SYN-Pakete werden von der SYN-Warteschlange nicht verarbeitet
  • Nachfolgende ACK-Pakete (zum Herstellen einer Verbindung) werden von der SYN-Warteschlange nicht verarbeitet
  • TcpExtListenOverflows / LINUX_MIB_LISTENOVERFLOWS-Anzahl steigt
  • TcpExtListenDrops / LINUX_MIB_LISTENDROPS-Anzahl steigt

In diesem Fall können wir nur hoffen, dass sich die Verarbeitungsleistung des Programms später wieder normalisiert und der Client die vom Server verworfenen Pakete erneut versendet.

Dieses Verhalten des Kernels ist für die meisten Dienste akzeptabel. Dieses Verhalten lässt sich übrigens durch Anpassen des globalen Parameters net.ipv4.tcp_abort_on_overflow modifizieren, am besten ist es jedoch, diesen Parameter nicht zu ändern.

Sie können den Status des Überlaufs der Annahmewarteschlange beobachten, indem Sie die Anzahl von nstat beobachten:

$ nstat -az TcpExtListenDrops
TcpExtListenDrops 49199 0,0

Aber das ist eine globale Zählung. Es ist nicht intuitiv zu beobachten. Manchmal beobachten wir beispielsweise, dass es wächst, aber alle Serviceprogramme scheinen normal zu sein. An diesem Punkt können wir den Befehl ss verwenden, um die Größe der Akzeptanzwarteschlange eines einzelnen Abhörports zu beobachten:

$ ss -plnt sport = :6443|cat
Status Recv-Q Send-Q Lokale Adresse:Port Peer-Adresse:Port
LISTEN 0 1024 *:6443 *:*

Die Spalte „Recv-Q“ zeigt die Anzahl der Sockets in der Akzeptanzwarteschlange und „Send-Q“ zeigt die maximale Größe der Warteschlange. Im obigen Beispiel stellen wir fest, dass es keinen Socket gibt, der vom Programm nicht akzeptiert wurde (akzeptiert()), aber wir stellen trotzdem fest, dass die Anzahl der ListenDrops zunimmt.

Dies liegt daran, dass unser Programm nur für einen kurzen Zeitraum hängen bleibt und keine neuen Verbindungen verarbeitet, anstatt die Verarbeitung dauerhaft auszusetzen. Nach einer Weile kehrt das Programm zum Normalzustand zurück. In diesem Fall ist es schwierig, dieses Phänomen mit dem Befehl ss zu beobachten. Daher haben wir ein SystemTap-Skript geschrieben, das sich in den Kernel einklinkt und die verworfenen SYN-Pakete ausdruckt:

$ sudo stap -v acceptq.stp
Zeit (US) acceptq qmax lokale Adresse Remote-Adresse
1495634198449075 1025 1024 0.0.0.0:6443 10.0.1.92:28585
1495634198449253 1025 1024 0.0.0.0:6443 10.0.1.92:50500
1495634198450062 1025 1024 0.0.0.0:6443 10.0.1.92:65434
...

Durch die oben genannten Vorgänge können Sie beobachten, welche SYN-Pakete von ListenDrops betroffen sind. Auf diese Weise können wir auch feststellen, welche Programme die Verbindung verlieren.

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Simulieren Sie eine TCP-3-Wege-Handshake-Verbindung und senden Sie Daten basierend auf Python
  • Analyse des Prinzips und des Prozesses des Drei-Wege-Handshakes und der Vier-Wege-Welle im TCP/IP-Protokoll
  • Eine detaillierte Einführung in den Drei-Wege-Handshake und die Vier-Wege-Welle von TCP
  • Grundlegende Einführung in Wireshark und Erlernen des TCP-Drei-Wege-Handshakes
  • TCP-Drei-Wege-Handshake und Prinzip
  • Implementierung der Dateiübertragung basierend auf der TCP-Protokoll-Socket-Netzwerkprogrammierung in Java
  • Implementierungsprinzip und Prozessanalyse der TCP-Leistungsoptimierung
  • Java implementiert den Dateiupload basierend auf dem TCP-Protokoll
  • Diagramm des Datenübertragungsprozesses beim dritten TCP-Handshake

<<:  Tutorial zu HTML-Tabellen-Tags (32): Attribut für horizontale Zellenausrichtung ALIGN

>>:  MySQL kann tatsächlich verteilte Sperren implementieren

Artikel empfehlen

Detaillierte Erläuterung der Mybatis-Sonderzeichenverarbeitung

Vorwort: Mybatis-Sonderzeichenverarbeitung, Verar...

Analyse der Protokolldateien im Tomcat-Protokollverzeichnis (Zusammenfassung)

Bei jedem Start von Tomcat werden die folgenden P...

favico.ico --- Schritte zum Einrichten des Website-ICO-Symbols

1. Laden Sie die erfolgreich generierte Symboldate...

Die Qualitäten und Fähigkeiten, die ein Webdesigner haben sollte

Webdesign ist eine aufstrebende Randbranche, die n...

18 Killer-JavaScript-Einzeiler

Vorwort JavaScript erfreut sich weiterhin wachsen...

So konfigurieren Sie ein Jupyter-Notebook im Docker-Container

Das Jupyter-Notebook wird unter dem Docker-Contai...

Flexibles Boxmodell von CSS und CSS3 zur Anpassung der Elementbreite (-höhe)

1. CSS realisiert eine feste Breite links und ein...

Einführung in gängige XHTML-Tags

<br />Ich habe festgestellt, dass viele Leut...

Analyse des Unterschieds zwischen relativem und absolutem HTML-Pfad

Gerade HTML-Anfänger stehen häufig vor dem Problem...

Der Unterschied zwischen clientWidth, offsetWidth, scrollWidth in JavaScript

1. Konzept Sie alle sind Attribute des Elements u...

Einfaches Docker Swarm-Tutorial

Schwarm drei virtuelle Maschinen 132,133,134 1. I...

jQuery realisiert die Shuttle-Box-Funktion

In diesem Artikelbeispiel wird der spezifische Co...

Join-Operation in MySQL

Arten von Verknüpfungen 1. Innerer Join: Die Feld...