2012-07-29 67 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

相关问题