2012-07-29 65 views
10

我有一個node.js客戶端(10.177.62.7)從服務器(10.177.0.1)的http rest服務請求一些數據。客戶端只需使用node.js http.request()方法(agent = false)。客戶端在Ubuntu 11.10盒子上。客戶端發送延遲的FIN ACK(〜500ms)到服務器

爲什麼客戶端在475ms後發送FIN ACK?爲什麼這麼慢?他應該立即發送FIN ACK。我有很多這樣的情況。大約1%的流量是延遲FIN ACK的請求。

客戶端的Cpu閒置約爲99%,所以沒有任何東西正在消耗CPU。

如何調試?會是什麼呢? 是否有我需要調整的任何sysctl選項?

在屏幕截圖第二列是數據包之間經過的時間。

Link to bigger picture.

enter image description here

+0

我刪除了有關HTTP保持活動的答案,因爲它已被明確排除。儘管如此,我想不出任何其他答案。一旦插座關閉,FIN應該熄滅。 – 2012-07-29 21:23:14

+0

@AlanCurry但是,只有當客戶端讀取了傳入的FIN並決定關閉套接字時,* FIN/ACK *纔會消失,這可能需要很長時間。這是node.js的行爲,而不是TCP/IP堆棧。 – EJP 2012-07-30 00:11:28

+0

當然,但是如果它正在調用一個http客戶端庫的過程中,它不會保持活動狀態,並且CPU負載爲1%,那麼在讀取EOF之後關閉套接字需要多長時間? – 2012-07-30 00:15:39

回答

4

這種行爲是RFC1122 TCP stack延遲ACK功能。

通常你應該在TCP_QUICKACK選項添加到您的Linux TCP socketdisable delayed ACK但我認爲這不是很明顯的JavaScript Node.js的API(我只看到了socket.setNoDelayTCP_NODELAY選項)。

所以你的想法申請system-wide change on TCP stack似乎不錯,但我發現沒有sysctl匹配此套接字選項的行爲。這是另一個full list with explanation

+0

這看起來像正確的答案,除非有更多的細節OP沒有提供 – 2012-08-02 15:47:09

+0

感謝您的回答!我還有一些其他問題。這對FIN ACK有效或僅對「單獨」ACK有效。你能說明爲什麼內核延遲FIN/ACK。在tcpflow數據中,每個來自服務器的數據包都有一個ACK。爲什麼內核延遲客戶端FIN/ACK。它可以避免每個'數據'包發送ACK。但它選擇延遲FIN/ACK?這可能嗎? – Tereska 2012-08-02 18:23:57

+0

請閱讀RFC1122的4.2.3.2部分......它不是特定於FIN數據包。我同意你沒有理由推遲沒有數據的FIN + ACK數據包。我邀請您聯繫LKML上的Linux內核TCP團隊或延遲ACK邏輯實現的開源代碼。可能可以進行優化,至少有一個新的sysctl開關可以避免這種行爲。 – 2012-08-02 18:41:54

相關問題