2012-07-29 3 views
10

Ich habe einen node.js Client (10.177.62.7), der einige Daten vom http Rest Service vom Server (10.177.0.1) anfordert. Der Client verwendet einfach die Methode http.request() von node.js (agent = false). Client ist auf Ubuntu 11.10-Box.Der Client sendet eine verzögerte FIN ACK (~ 500ms) an den Server

Warum Client sendet FIN ACK nach 475ms? Warum so langsam? Er sollte FIN ACK sofort senden. Ich habe viele Situationen wie diese. Ungefähr 1% des gesamten Datenverkehrs ist eine Anfrage mit verzögertem FIN ACK.

Cpu Leerlauf auf dem Client ist etwa 99%, so dass nichts CPU entleert.

Wie debuggen Sie das? Was könnte es sein? Gibt es irgendeine sysctl Option, die ich tunen muss?

Auf Screenshot 2. Spalte ist die verstrichene Zeit zwischen den Paketen.

Link to bigger picture.

enter image description here

+0

Ich löschte meine Antwort über HTTP Keep-Alive, da es definitiv ausgeschlossen wurde. Ich denke jedoch nicht an andere Antworten. Das FIN sollte ausgehen, sobald die Steckdose geschlossen ist. –

+0

@AlanCurry Aber das * FIN/ACK * würde nur ausgehen, wenn der Client das eingehende FIN gelesen hat und entschieden hat, den Socket zu schließen, was eine gewisse Zeit dauern kann. Dies ist ein Verhalten von node.js, nicht der TCP/IP-Stack. – EJP

+0

Sicher, aber wenn es in der Mitte eines Aufrufs zu einer HTTP-Client-Bibliothek ist, macht es Keep-Alive nicht, und die CPU-Last ist 1%, was dauert es so lange, den Socket nach dem Lesen von EOF zu schließen? –

Antwort

4

Dieses Verhalten ist die verzögerte ACK-Funktion von RFC1122 TCP stack.

Normalerweise sollten Sie die TCP_QUICKACK Option zu Ihrem Linux TCP socket-disable delayed ACK hinzufügen, aber ich denke, es mit JavaScript Node.js-API nicht offensichtlich ist (ich sah nur socket.setNoDelay für TCP_NODELAY Option).

So scheint Ihre Idee, eine system-wide change on TCP stack gelten gut, aber ich fand keine sysctl passend dieses Socket-Option Verhalten. Hier ist ein weiterer full list with explanation.

+0

Das sieht wie die richtige Antwort aus, es sei denn, es gibt mehr Details, die das OP nicht zur Verfügung gestellt hat –

+0

Danke für Ihre Antwort! Ich habe einige zusätzliche Fragen. Ist das für FIN ACK oder nur für "allein" ACK gültig? Können Sie sagen, warum der Kernel das FIN/ACK verzögert hat? In tcpflow-Daten gibt es genau ein ACK pro Paket, das vom Server kommt. Warum hat der Kernel den Client FIN/ACK verzögert? Es könnte vermieden werden, ACK jedes "Daten" -Paket zu senden. Aber es verzögert FIN/ACK? Ist das möglich? – Tereska

+0

Bitte lesen Abschnitt 4.2.3.2 von RFC1122 ... es ist nicht spezifisch für FIN-Pakete. Ich stimme Ihnen zu, dass es keinen Grund gibt, ein FIN + ACK-Paket ohne Daten zu verzögern. Ich lade Sie ein, Linux-Kernel-TCP-Team auf LKML oder Open-Source-Code für verzögerte ACK-Logik-Implementierung zu kontaktieren.Wahrscheinlich kann eine Optimierung durchgeführt werden und zumindest ein neuer sysctl-Schalter, um dieses Verhalten zu vermeiden. –

Verwandte Themen