2012-07-29 12 views
10

Mam klienta node.js (10.177.62.7) żądającego pewnych danych z usługi reszty http z serwera (10.177.0.1). Klient po prostu używa metody http.request() node.js (agent = fałsz). Klient jest w systemie Ubuntu 11.10.Klient wysyła z opóźnieniem FIN ACK (~ 500ms) na serwer

Dlaczego klient wysyła FIN ACK po 475ms? Dlaczego tak wolno? Powinien natychmiast wysłać FIN ACK. Mam wiele takich sytuacji. Około 1% całego ruchu pochodzi z opóźnionego potwierdzenia FIN.

Cpu bezczynności na kliencie wynosi około 99%, więc nic nie opróżnia procesora.

Jak to debugować? Co to mogło być? Czy jest jakaś opcja sysctl, którą muszę dostroić?

Na zrzucie ekranu Druga kolumna to czas, jaki upłynął między pakietami.

Link to bigger picture.

enter image description here

+0

Usunąłem moją odpowiedź na temat zachowania HTTP, ponieważ zostało definitywnie wykluczone. Nie mogę jednak wymyślić żadnych innych odpowiedzi. FIN powinno wyjść, gdy tylko gniazdo zostanie zamknięte. –

+0

@AlanCurry Ale * FIN/ACK * może wyjść tylko wtedy, gdy klient odczyta przychodzące FIN i zdecyduje się zamknąć gniazdo, co może zająć dowolną ilość czasu. Jest to zachowanie pliku node.js, a nie stosu TCP/IP. – EJP

+0

Oczywiście, ale jeśli jest w trakcie połączenia z biblioteką klienta http, nie działa on w trybie podtrzymywania, a obciążenie procesora wynosi 1%, co zajmuje tak długo, aby zamknąć gniazdo po przeczytaniu EOF? –

Odpowiedz

4

Takie zachowanie jest cechą Opóźnione ACK od RFC1122 TCP stack.

Normalnie należy dodać opcję TCP_QUICKACK aby Twój Linux TCP socket do disable delayed ACK ale myślę, że nie jest to oczywiste z JavaScript node.js API (widziałem tylko socket.setNoDelay dla TCP_NODELAY opcja).

Twój pomysł zastosowania system-wide change on TCP stack wydaje się dobry, ale nie znalazłem sysctl pasujących do tego zachowania opcji gniazda. Oto kolejny full list with explanation.

+0

To wygląda na właściwą odpowiedź, chyba że jest więcej szczegółów, że OP nie dostarczył –

+0

Dziękuję za odpowiedź! Mam dodatkowe pytania. Czy jest to ważne dla FIN ACK lub tylko dla "samego" ACK. Czy możesz powiedzieć, dlaczego jądro opóźniało FIN/ACK. W danych tcpflow jest tylko jeden ACK na pakiet przychodzący z serwera. Dlaczego jądro opóźnia klienta FIN/ACK. Mogłoby to uniknąć wysyłania ACK każdego pakietu "danych". Ale decyduje się opóźnić FIN/ACK? czy to możliwe? – Tereska

+0

Przeczytaj sekcję 4.2.3.2 RFC1122 ... nie jest ona specyficzna dla pakietów FIN. Zgadzam się z Państwem, że nie ma powodu, aby opóźniać pakiet FIN + ACK bez danych. Zapraszam do skontaktowania się z zespołem Linux jądra TCP na LKML lub open source kod dla opóźnionej implementacji logiki ACK.Prawdopodobnie można przeprowadzić optymalizację i przynajmniej nowy przełącznik sysctl, aby uniknąć tego zachowania. –

Powiązane problemy