据我所知tcp延迟ack一直是200ms,但是现在在我的生产环境中延迟将近600ms,我的环境如下:ubuntu 11.04 48G内存16核,负载不重;我在服务器端抓包(6380是服务器端口),数据包如下,我们可以看到在16:29:24.036999时刻服务器收到了客户端发来的数据包,但是直到16:29:24.634244时刻服务器才回复ack,持续了将近600ms,而客户端设置的超时时间为500ms,所以它关闭了连接。
600ms+ delay ack packet
16:29:12.458770 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [.], ack 11504, win 1107, length 0
16:29:15.070423 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [P.], seq 9756:9790, ack 11504, win 1107, length 34
16:29:15.070497 IP 192.168.70.134.6380 > 192.168.60.71.22142: Flags [P.], seq 11504:11514, ack 9790, win 848, length 10
16:29:15.070568 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [.], ack 11514, win 1107, length 0
16:29:16.951893 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [P.], seq 9790:9842, ack 11514, win 1107, length 52
16:29:16.951983 IP 192.168.70.134.6380 > 192.168.60.71.22142: Flags [P.], seq 11514:11620, ack 9842, win 848, length 106
16:29:16.952100 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [.], ack 11620, win 1107, length 0
16:29:18.469622 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [P.], seq 9842:9894, ack 11620, win 1107, length 52
16:29:18.469761 IP 192.168.70.134.6380 > 192.168.60.71.22142: Flags [P.], seq 11620:11721, ack 9894, win 848, length 101
16:29:18.469839 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [.], ack 11721, win 1107, length 0
16:29:20.202913 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [P.], seq 9894:10710, ack 11721, win 1107, length 816
16:29:20.203026 IP 192.168.70.134.6380 > 192.168.60.71.22142: Flags [P.], seq 11721:11726, ack 10710, win 863, length 5
16:29:20.203157 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [.], ack 11726, win 1107, length 0
16:29:21.893243 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [P.], seq 10710:10744, ack 11726, win 1107, length 34
16:29:21.893354 IP 192.168.70.134.6380 > 192.168.60.71.22142: Flags [P.], seq 11726:11736, ack 10744, win 863, length 10
16:29:21.893487 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [.], ack 11736, win 1107, length 0
16:29:24.036999 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [P.], seq 10744:10796, ack 11736, win 1107, length 52
16:29:24.240657 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [P.], seq 10744:10796, ack 11736, win 1107, length 52
16:29:24.536929 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [F.], seq 10796, ack 11736, win 1107, length 0
16:29:24.634244 IP 192.168.70.134.6380 > 192.168.60.71.22142: Flags [P.], seq 11736:12057, ack 10796, win 863, length 321
16:29:24.634410 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [F.], seq 10796, ack 11736, win 1107, length 0
16:29:24.634470 IP 192.168.60.71.22142 > 192.168.70.134.6380: Flags [R], seq 554218496, win 0, length 0
800ms delay ack packet
16:37:01.921951 IP 192.168.60.72.23935 > 192.168.70.135.6380: Flags [P.], seq 40135:40187, ack 42430, win 1081, length 52
16:37:01.922029 IP 192.168.70.135.6380 > 192.168.60.72.23935: Flags [P.], seq 42430:42655, ack 40187, win 1345, length 225
16:37:01.922097 IP 192.168.60.72.23935 > 192.168.70.135.6380: Flags [.], ack 42655, win 1081, length 0
16:37:04.569001 IP 192.168.60.72.23935 > 192.168.70.135.6380: Flags [P.], seq 40187:40239, ack 42655, win 1081, length 52
16:37:04.770636 IP 192.168.60.72.23935 > 192.168.70.135.6380: Flags [P.], seq 40187:40239, ack 42655, win 1081, length 52
16:37:05.069588 IP 192.168.60.72.23935 > 192.168.70.135.6380: Flags [F.], seq 40239, ack 42655, win 1081, length 0
16:37:05.178638 IP 192.168.60.72.23935 > 192.168.70.135.6380: Flags [P.], seq 40187:40239, ack 42655, win 1081, length 52
16:37:05.442263 IP 192.168.70.135.6380 > 192.168.60.72.23935: Flags [P.], seq 42655:42832, ack 40239, win 1345, length 177
16:37:05.443329 IP 192.168.70.135.6380 > 192.168.60.72.23935: Flags [.], ack 40239, win 1345, options [nop,nop,sack 1 {40187:40239}], length 0
16:37:05.443484 IP 192.168.60.72.23935 > 192.168.70.135.6380: Flags [F.], seq 40239, ack 42655, win 1081, length 0
16:37:05.445463 IP 192.168.70.135.6380 > 192.168.60.72.23935: Flags [F.], seq 42832, ack 40240, win 1345, options [nop,nop,sack 1 {40239:40240}], length 0
16:37:05.448999 IP 192.168.60.72.23935 > 192.168.70.135.6380: Flags [R], seq 4279187611, win 0, length 0
答案1
RFC 1122 第 4.2.3.2 节规定 ACK 最多可延迟 500 毫秒:
A TCP SHOULD implement a delayed ACK, but an ACK should not be excessively delayed; in particular, the delay MUST be less than 0.5 seconds, and in a stream of full-sized segments there SHOULD be an ACK for at least every second segment.
不急于发送 ACK。不过这里有些奇怪,重新传输似乎太快了。
答案2
如果您在 tcpdump 中看到数据包,它只会显示数据包已到达机器。但是,只有当内核可以将数据包传送到应用程序的套接字缓冲区中时,它才会创建 ACK。这可能会失败,因为数据包被数据包过滤器阻止,或者因为系统内存不足,但最可能的情况是应用程序的套接字缓冲区已满,因为它在短时间内收到大量数据并且无法处理所有数据。
在这种情况下,即使数据包到达系统,也会丢失,因此不会生成 ACK,发送方必须重新传输数据包。如果应用程序已准备就绪,并且套接字缓冲区中有空间,则可以立即传送数据包,否则数据包将丢失,并且不会再次发送 ACK。