TCP网络拥塞

详解

在网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包时延、丢失等,这时 TCP 就会重传数据,但是一重传就会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这个情况就会进入恶性循环被不断地放大……

所以,TCP 不能忽略网络上发生的事,它被设计成一个无私的协议,当网络发送拥塞时,TCP 会自我牺牲,降低发送的数据量。

于是,就有了拥塞控制,控制的目的就是避免「发送方」的数据填满整个网络。

为了在「发送方」调节所要发送数据的量,定义了一个叫做「拥塞窗口」的概念。

拥塞窗口 cwnd是发送方维护的一个的状态变量,它会根据网络的拥塞程度动态变化的。

我们在前面提到过发送窗口 swnd 和接收窗口 rwnd 是约等于的关系,那么由于加入了拥塞窗口的概念后,此时发送窗口的值是swnd = min(cwnd, rwnd),也就是拥塞窗口和接收窗口中的较小值。

拥塞窗口 cwnd 变化的规则:

只要网络中没有出现拥塞,cwnd 就会增大;

但网络中出现了拥塞,cwnd 就减少;

只要「发送方」没有在规定时间内接收到 ACK 应答报文,也就是发生了超时重传,就会认为网络出现了拥塞。

拥塞控制算法:

  • 慢启动:

当发送方每收到一个 ACK,拥塞窗口 cwnd 的大小就会加 1(表示能发送1个MSS大小)

有一个叫慢启动门限 ssthresh (slow start threshold,65535字节)状态变量。

- 当 cwnd < ssthresh 时,使用慢启动算法。 
- 当 cwnd >= ssthresh 时,就会使用「拥塞避免算法」。 
  • 拥塞避免算法:

每当收到一个 ACK 时,cwnd 增加 1/cwnd。

  • 拥塞发生:

当网络出现拥塞,也就是会发生数据包重传,重传机制主要有两种:

- 超时重传,一直没收到ACK,从丢失的ACK开始超时重传 
- 快速重传,收到三个相同的ACK,表明某个包丢失了,快速重传丢失的包 
- 当发生了「超时重传」,则就会使用拥塞发生算法 

这个时候,ssthresh 和 cwnd 的值会发生变化:

    * ssthresh 设为 cwnd/2, 
    * cwnd 重置为 1(假设为1,其实是恢复为 cwnd 初始化值,默认初始值为10) 

接着,就重新开始慢启动

这种方案会导致如果只丢了一个包,却要立马刹车减速回到解放前, 重新慢启动

- 当发生了「快速重传」,TCP 认为这种情况不严重,因为大部分没丢,只丢了一小部分,则 ssthresh 和 cwnd 变化如下: 
    * cwnd = cwnd/2 ,也就是设置为原来的一半; 
    * ssthresh = cwnd; 
    * 进入快速恢复算法 
    * 即慢启动门限和拥塞窗口都变为拥塞窗口的一半 
  • 快速恢复:

快速重传和快速恢复算法一般同时使用,快速恢复算法是认为,你还能收到 3 个重复 ACK 说明网络也不那么糟糕,所以没有必要像 RTO 超时那么强烈。算法如下:

- 拥塞窗口 cwnd = ssthresh + 3 ( 3 的意思是确认有 3 个数据包被收到了),之前设置为ssthresh = cwnd,所以其实这里就是设为cwnd = cwnd/2 + 3;如下图为12变成9 
- 重传丢失的数据包; 
- 如果再收到重复的 ACK,那么 cwnd 增加 1; 
- 如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh (cwnd / 2)的值,原因是该 ACK 确认了新的数据,说明从 duplicated ACK 时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态; 

为什么收到新数据后cwnd变为ssthresh?

首先,快速恢复是拥塞发生后慢启动的优化,其首要目的仍然是降低 cwnd 来减缓拥塞,所以必然会出现 cwnd 从大到小的改变。

其次,cwnd逐渐加1的存在是为了尽快将丢失的数据包发给目标,从而解决拥塞的根本问题(三次相同的 ACK 导致的快速重传),所以这一过程中 cwnd 反而是逐渐增大的。

面试快答

TCP的拥塞控制主要通过慢启动、拥塞避免、快速重传和快速恢复等机制来运作。

初始阶段,TCP使用慢启动算法,每次收到一个 ACK,窗口大小就翻倍,这个阶段窗口是指数增长。

当拥塞窗口达到慢启动阈值后,进入拥塞避免阶段,此时窗口是线性增长。

如果检测到数据包丢失(通过超时或重复ACK),TCP会启动快速重传机制,立即重传丢失的数据包。

并且窗口会调整为原本窗口的 1/2,也就是快开始。

而后进入快速恢复(快开始)阶段,保持窗口线性增长。

这些机制共同作用,确保了TCP在避免网络拥塞的同时,提供稳定可靠的数据传输。

简述

慢启动指数增长,拥塞避免线性增长,快速重传窗口减半,快速恢复线性增长;