Zum Hauptinhalt springen

Die TCP-Backlog-Erfassung ist ein Effekt, der verhindert, dass eine Serveranwendung auf dem Modul Stratus , die auf Port X lauscht, erfolgreich eine Verbindung mit einem Client herstellen kann, der versucht, eine Verbindung zu Port X herzustellen. Verbindungen zu anderen Ports, selbst von denselben Clients, funktionieren problemlos. Die typische Lösung besteht darin, die Serveranwendung herunterzufahren und neu zu starten. In diesem Beitrag wird erklärt, warum es zu einem Rückstau kommt und welche anderen, weniger drastischen Lösungen es gibt.

Der TCP-Backlog ist die Warteschlange der ausstehenden Verbindungen, d. h. Verbindungsanforderungen, die empfangen, aber noch nicht akzeptiert wurden. In Anwendungen, die auf Versionen vor OpenVOS 17.1 kompiliert wurden, und in Anwendungen, die auf OpenVOS 17.1, aber ohne die POSIX-Bibliotheken kompiliert wurden, werden Verbindungsanfragen erst dann bestätigt, wenn sie von der Anwendung angenommen wurden. Der Client sendet das Verbindungsanforderungspaket zwischen 3 und 10 Mal in zunehmenden Abständen erneut. Die genauen Einzelheiten hängen vom Client-Betriebssystem und dessen Konfiguration ab. Irgendwann nimmt die Serveranwendung die Verbindungsanforderung an und der STCP-Stack sendet eine Bestätigung. Solange diese Bestätigung empfangen wird, bevor der Client aufgegeben hat, ist die Verbindung abgeschlossen und die Kommunikation kann beginnen.

Das Szenario der Rückstandserfassung erfordert mehrere Bedingungen

  1. Es liegt ein vorübergehender Netzwerkausfall zwischen Server und Client (aber nicht zwischen Client und Server) vor. Dadurch können die Verbindungsanfragen des Clients vom Server empfangen werden, aber die Verbindungsbestätigungen des Servers können vom Client nicht empfangen werden.
    oder

    Die Serveranwendung verzögert den Aufruf der Akzeptfunktion aus irgendeinem Grund.

  2. Der Client sendet weiterhin Verbindungsanfragen, d. h. wenn die aktuelle Anfrage abgelaufen ist, sendet der Client eine neue Anfrage. Der Timeout-Wert des Clients muss kürzer sein als der Timeout-Wert des Servers.
  3. Eine Stateful-Firewall oder ein anderes Gerät, das sich zwischen dem Client und dem Server befindet, sorgt dafür, dass die Verbindungsanfragen des Clients verzögert und die Verbindungsbestätigungen des Servers verworfen werden, ohne dass eine Antwort an den Server zurückgesendet wird. Dieser Timeout-Wert muss kürzer sein als der Timeout-Wert des Servers.

Leider ist diese Kombination von Bedingungen nicht so unwahrscheinlich, wie es auf den ersten Blick erscheinen mag.

Er beginnt in der Regel mit einem Netzausfall, der verhindert, dass Pakete vom Server den Client erreichen, aber Pakete vom Client zum Server durchlässt. Wenn das Paket mit der Verbindungsanfrage des Clients den Server erreicht, wird es in die Backlog-Warteschlange gestellt. Wenn die Serveranwendung den Accept-Code aufruft, holt der Code die Verbindungsanforderung aus der Backlog-Warteschlange und sendet eine Verbindungsbestätigung. Da der Server keine Bestätigung für sein Paket erhält, weil das Netzwerk unterbrochen ist, sendet er die Verbindungsbestätigung erneut. Der TCP-Stack des Clients sendet die Verbindungsanforderung ebenfalls erneut, da er keine Bestätigung erhalten hat. Nach einer Weile gibt der TCP-Stack des Clients auf und die Client-Anwendung sendet eine neue Anfrage. Der Server antwortet weiterhin auf die erste Anfrage. Nach etwa anderthalb Minuten (standardmäßig) gibt der Server eine Zeitüberschreitung ein und holt die nächste Anfrage aus der Warteschlange. In der Zwischenzeit hat der Client die zweite Anfrage erneut gesendet und ist möglicherweise schon bei der dritten. Diese Anfragen befinden sich ebenfalls in der Backlog-Warteschlange. Es ist möglich, dass ein anderer Client eine Verbindungsanfrage in die Backlog-Warteschlange stellen kann, aber für einen erfolgreichen Abschluss bräuchte der Client eine Zeitüberschreitung, die größer ist als die Server-Zeitüberschreitung multipliziert mit der Position der Verbindungsanfrage in der Backlog-Warteschlange. Sobald der Netzwerkausfall behoben ist, setzt die Stateful-Firewall den Ausfall fort, indem sie Verbindungsbestätigungen, für die sie keinen Status mehr hat, stillschweigend verwirft, da sie den Status nur für eine Zeitspanne aufrechterhält, die kürzer ist als der Server-Timeout.

Woran erkennen Sie das?

Zunächst ist die Warteschlange voll oder füllt sich zumindest. Mit diesem Befehl können Sie die Backlog-Warteschlange für eine Verbindung anzeigen.

analyze_system -request_line (string match backlog -oder syncnt (byte 3Bx) dump_st +
cbq -full -lport 7654 -faddr 0x) -quit 
OpenVOS Release 17.0.2au, analyze_system Release 17.0.2au 
Aktueller Prozess ist 154, ptep 91CC7100, Noah_Davids.CAC 
syncnt 6 
Rückstand 5 
bereit 11:41:19

Der Wert lport ist die lokale Portnummer, in diesem Fall 7654. Der Wert für die Fremdadresse (faddr) von 0 begrenzt die Ausgabe auf den Socket LISTENING. Wenn der backlog-Wert plus 1 gleich dem syncnt-Wert ist, ist der Backlog voll. Ist der syncnt-Wert größer als 0 und steigt an, füllt sich die Backlog-Warteschlange. Die Größe der Backlog-Warteschlange wird von der Anwendung festgelegt, wenn sie die Funktion listen aufruft.

Zweitens müssen Sie sich einen Netzwerkprotokoll-Trace ansehen. Daraus geht hervor, dass die letzte Verbindungsanforderung nicht bestätigt wird, während es Verbindungsbestätigungen für eine frühere Verbindungsanforderung gibt und diese Bestätigungen keine Antwort erhalten.

Die Kurve in Abbildung 1 zeigt dies. Jede Verbindung ist mit einem Stream-Index gekennzeichnet und ebenfalls farblich kodiert. Die erste Verbindungsanforderung vom Client befindet sich in Frame 1 zur Zeit 0. Die Bestätigung wird in Frame 2 gesendet und dann in Frame 3 erneut übertragen. In Frame 4 überträgt der Client die Verbindungsanforderung erneut. Da STCP bereits Verbindungsbestätigungen sendet, löst Frame 4 lediglich eine TCP-Bestätigung in Frame 5 aus. Die Frames 6 und 7 sind erneut gesendete Verbindungsbestätigungen. Frame 8 ist eine erneut gesendete Verbindungsanforderung vom Client. Frame 9 ist die TCP-Bestätigung, die durch die erneut übermittelte Verbindungsanforderung ausgelöst wird, und Frame 10 ist eine weitere erneut übermittelte Verbindungsbestätigung. Frame 11 ist eine weitere Verbindungsanforderung des Clients, jedoch für eine neue zweite Verbindung. Es erfolgt keine Antwort, und Frame 12 zeigt eine erneut übermittelte Verbindungsanforderung. Rahmen 13 zeigt eine Verbindungsbestätigung, aber immer noch für die erste Verbindung. Rahmen 14 ist eine erneute Übertragung der zweiten Verbindungsanforderung. Bild 14 ist eine erneute Übertragung der zweiten Verbindungsanforderung. Bild 15 zeigt eine neue, dritte Verbindungsanforderung vom Client und die Bilder 16 und 17 sind Wiederholungen. Bild 18 ist eine erneute Übertragung der Verbindungsbestätigung für die erste Verbindung. Rahmen 19 ist eine weitere Verbindungsanforderung, die Rahmen 20 und 21 sind Wiederholungen und Rahmen 22 ist die vierte neue Verbindungsanforderung. Schließlich gibt STCP in Frame 23 die erste Verbindungsanforderung auf und sendet einen Reset, gefolgt von einer Verbindungsbestätigung in Frame 24 für die zweite Verbindungsanforderung mit einer erneuten Übertragung in Frame 25. Ich denke, Sie verstehen jetzt, worum es geht.

STCP benötigte von Frame 0 bis Frame 23 für die Zeitüberschreitung, also insgesamt 106,9 Sekunden. Zwar sendet der Client bei Zeitüberschreitung keinen Reset, doch beträgt die Zeit zwischen dem Beginn der zweiten und dritten Verbindungsanforderung (Frame 11 bis Frame 15) 29,152 Sekunden und zwischen der dritten und vierten (Frames 15 und 19) 25,8 Sekunden, also wesentlich schneller als bei STCP.

Was können Sie tun, um dies zu verhindern?

Die beste Lösung ist ein Upgrade auf OpenVOS 17.1 und eine Neukompilierung der Anwendung mit den POSIX-Bibliotheken. Dadurch wird verhindert, dass das Problem überhaupt auftritt, da STCP sofort eine Verbindungsbestätigung sendet, ohne auf den Aufruf von accept durch die Anwendung zu warten. Allerdings können sich dadurch andere Verhaltensweisen Ihrer Anwendung ändern, weshalb Sie Ihre Anwendung sorgfältig testen sollten. Wenn eine Aktualisierung und Neukompilierung nicht möglich ist, können Sie

  1. Konfigurieren Sie das zustandsabhängige Netzwerkgerät, das die Verbindungsbestätigungen verwirft, so um, dass es mit einem Reset reagiert. Wenn STCP die Rücksetzung empfängt, wird es zur nächsten Verbindungsanforderung in der Warteschlange übergehen. Das Ergebnis ist, dass die Verbindungsanforderungen, die vom zustandsbehafteten Gerät abgebrochen wurden, schnell aus der Warteschlange entfernt werden. Alle weiteren Verbindungsbestätigungen werden vom Client bearbeitet, der entweder einen eigenen Reset sendet oder sie quittiert.
  2. Halten Sie den Client davon ab, Verbindungsanfragen zu stellen, bis die Rückstandswarteschlange des Servers geleert ist.
  3. Schließen Sie den Listening-Socket der Serveranwendung und öffnen Sie ihn erneut. Normalerweise ist die Anwendung nicht dafür ausgelegt, so dass Sie die Serveranwendung anhalten und neu starten müssen.
  4. Konfigurieren Sie den Wert von syn_rcvd_abort auf einen Wert, der kürzer ist als der Timeout-Wert des Clients. Der Wert wird mit der analyze_system-Anfrage set_stcp_param geändert
    analyze_system -request_line 'set_stcp_param syn_rcvd_abort 15' -quit
    OpenVOS Release 17.0.2au, analyze_system Release 17.0.2au 
    Aktueller Prozess ist 151, ptep 91530AC0, Noah_Davids.CAC 
    Ändern von tcp SYN_RCVD timeout (syn_rcvd_abort) von off auf 15 
    bereit 11:07:44

    Im obigen Beispiel ist die Zeitüberschreitung auf 15 Sekunden eingestellt. Die gültigen Werte liegen zwischen 1 und 180, wobei ein Wert von 0 bedeutet, dass der Standardwert (etwa 100 Sekunden) verwendet wird.

    Dadurch wird verhindert, dass ein einzelner Client einen großen Stau in der Warteschlange verursacht. Wie kurz der Wert sein sollte, hängt davon ab, wie viele Clients gleichzeitig auf den Server zugreifen können. Das Problem bei diesem Ansatz ist, dass er sich auf alle Clients und alle Server-Ports auswirkt, Sie können also nicht einen Wert für eine Gruppe von Ports und einen anderen für eine andere Gruppe von Ports festlegen. Außerdem kann ein zu niedriger Wert dazu führen, dass einige Verbindungen, die über Verbindungen mit hoher Latenz laufen, fehlschlagen, obwohl sie bei einem längeren Timer erfolgreich wären. Die Wahl eines optimalen Wertes ist mehr Kunst als Wissenschaft

© 2020 Stratus Technologies.