TCP:Nagle算法和延迟确认
Nagle 算法(Nagle’s Algorithm)和延迟确认(Delayed ACK)是两种用于提高 TCP 协议性能的机制。它们旨在减少网络中的小数据包数量,从而提高网络效率。然而,这两种机制有时也会相互影响,导致性能问题。
Nagle算法
Nagle算法作用于发送端,其目的在于通过减少小数据包的发送,来减少网络的拥塞。
在讲解TCP三次握手的时候,我们提到TCP头部结构,其大小为20~60个字节。设想一下,如果我们要发送一个字节的数据,为了这一个字节,我们需要加上20字节的TCP头部,再加了20字节的IP头部,一共40字节的头部,就为了搭载这一个字节的数据,显得效率太低,于是就有了Nagle算法:
- 发送数据时,如果当前有尚未确认的数据(已发出数据但还没收到ACK),则将数据缓存起来。
- 当所有未确认的数据都被确认后,TCP会发送缓冲区中的数据。
- 如果缓冲区的数据大于
MSS
时,也会直接发送缓冲区的数据。
MSS(Maxinum Segment Size)
指最大报文段长度,MSS
的常见计算方式为MTU
(最大传输单元)减去20字节的TCP头部和20字节的IP头部,通常MSS
值设置为1460
字节。这个值有助于避免 IP 分片。
当启用Nagle算法的时候,我们发送多个小包,就会被合成一个大包,以及来减少网络中数据包的数量。但是,对于实时性要求较高的应用,这样做相当于带来延迟,并不适合。
我们可以通过设置TCP_NODELAY
选项来关闭Nagle算法:
1 |
|
延迟确认
Nagle算法是从发送端减少包的数据,而延迟确认则是从接收方的角度,通过减少ACK
的数量,还达到减少网络拥塞的目的。
- 当
TCP
收到数据包后,不立即发送ACK
,而是等待一小段时间(通常是 200 毫秒)。 - 在这个等待时间内,如果有数据需要发送,则将
ACK
和数据一起发送,这样可以减少单独的ACK
包。 - 在这个等待时间内,如果收到第二份数据,则发送
ACK
。 - 如果等待时间到期,还没有数据要发送,则发送
ACK
。
TCP 连接中,客户端发送数据包,服务器收到后,如果立即发送 ACK,网络中会有大量的 ACK 包。启用延迟确认后,服务器在接收数据包后会等待一段时间,如果在这段时间内客户端继续发送数据,服务器可以一起确认多个数据包,减少 ACK 包数量。
Nagle算法和延迟确认导致的性能问题
Nagle在发送数据的环节增加了延迟,而延迟确认在接收的环节增加了延迟,如果发送方一直发小包,而接收方也没有数据返回的时候,可能会造成更多的延迟:
所以,在对延迟比较敏感的应用中,通常会关闭Nagle
算法,来提高延迟。