1.网络拥塞
上一集我们提到了网络就像一条高速公路,我们发送的数据就像一辆辆车,这条公路不是无限宽的,当我们的车足够多的时候公路就会堵车,回想一下我们每天上网的时候,是不是一到大家下班的时间,网络就会卡顿呢?这是因为网络上的数据包太多了,将我们的网络带宽占满了,这时候网速就会下降,甚至是数据包丢失,更严重的情况甚至会导致网络瘫痪,这就是为什么有了流量控制还要有拥塞控制,TCP被设置为一个无私的协议,在发生网络拥塞的时候就会牺牲自己,限制自己的发送速度从而减小网络的压力。
1.拥塞窗口
和流量控制一样,拥塞控制也有一个窗口,拥塞窗口(cwnd),写到这里突然发现上一章忘了写缩写,这里补一下:发送窗口(swnd),接收窗口(rwnd),拥塞窗口是发送方维护的一个动态窗口,发送窗口和接收窗口是约等于的关系,那么由于加入了拥塞窗口的概念后,此时发送窗口的值是swnd = min(cwnd, rwnd),也就是拥塞窗口和接收窗口中的最小值。
拥塞窗口有对于不同情况的变化规律:
网络拥塞时:乘性减,既然拥塞已经发生,就要最快速度减小自己对于网络的压力
网络通畅时:加性增,网络虽然通畅但是毕竟不是无限的,所以要缓慢增加自己的扩大速度
说了这么多网络拥塞,那么如何判断自己是否出现了拥塞呢?之前我们提过,在网络通畅的情况下丢包的概率是接近于0的,即使真的丢包也会发生快速重传,所以当网络足够慢的时候,才会发生超时重传,所以出现了超时重传就认定发生了网络拥塞
2.拥塞控制
对于拥塞的控制,使用了以下四种算法
1.慢启动
慢启动的算法记住一个规则:当发送方每收到一个 ACK,拥塞窗口 cwnd 的大小就会加 1。
这里可以看出,慢启动算法是呈指数型增长,但是指数有一个非常可怕的问题——指数爆炸,如此增长下去,这个窗口会在某一刻增长到一个非常可怕的大小,这种情况只会越来越遭,那么应该增长到什么时候呢?
门限值
慢启动算法对应了一个门限值,也就是他的限制,
慢启动门限状态变量ssthresh (slow start threshold)
当窗口大小小于门限值时继续使用慢启动算法,当窗口大小到达门限值后就切换到下一个算法
2.拥塞避免
进入拥塞避免算法后窗口还会继续增长,但是增长速度有所改变每当收到一个 ACK 时,cwnd 增加 1/cwnd。
所以,我们可以发现,拥塞避免算法就是将原本慢启动算法的指数增长变成了线性增长,还是增长阶段,但是增长速度缓慢了一些。就这么一直增长着后,网络就会慢慢进入了拥塞的状况了,于是就会出现丢包现象,这时就需要对丢失的数据包进行重传。
当触发了重传机制,也就进入了「拥塞发生算法」。
3.拥塞发生
当网络发生拥塞就会触发重传机制,而重传机制分为两种:
超时重传
快速重传
他们又分别对应了两种拥塞控制算法
1.拥塞发生算法(超时重传)
当出现超时重传的情况就会启用拥塞发生算法,因为当确定网络发生拥塞时,无疑是最糟糕的情况,这时窗口就会骤然减小
- ssthresh 设为 cwnd/2,
- cwnd 重置为 1 (恢复为 cwnd 初始化值,这里假定 cwnd 初始化值 1)
接着,就重新开始慢启动,慢启动是会突然减少数据流的。这真是一旦「超时重传」,马上回到解放前。但是这种方式太激进了,反应也很强烈,会造成网络卡顿。
2.拥塞发生算法(快重传)
当接收方发现丢了一个中间包的时候,发送三次前一个包的 ACK,于是发送端就会快速地重传,不必等待超时再重传。
TCP 认为这种情况不严重,因为大部分没丢,只丢了一小部分,则 ssthresh 和 cwnd 变化如下:
cwnd = cwnd/2 ,也就是设置为原来的一半;
ssthresh = cwnd;
4.快恢复
快速重传和快速恢复算法一般同时使用,快速恢复算法是认为,你还能收到 3 个重复 ACK 说明网络也不那么糟糕,所以没有必要像 RTO 超时那么强烈。
正如前面所说,进入快速恢复之前,cwnd 和 ssthresh 已被更新了:
- cwnd = cwnd/2 ,也就是设置为原来的一半;
- ssthresh = cwnd;
然后,进入快速恢复算法如下:
- 拥塞窗口 cwnd = ssthresh + 3 ( 3 的意思是确认有 3 个数据包被收到了);
- 重传丢失的数据包;
- 如果再收到重复的 ACK,那么 cwnd 增加 1;
- 如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh 的值,原因是该 ACK 确认了新的数据,说明从 duplicated ACK 时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态;
也就是没有像「超时重传」一夜回到解放前,而是还在比较高的值,后续呈线性增长。
为什么这个算法中收到了新的数据时cwnd会设置为门限值大小呢?
首先,快速恢复是拥塞发生后慢启动的优化,其首要目的仍然是降低 cwnd 来减缓拥塞,所以必然会出现 cwnd 从大到小的改变。
其次,过程2(cwnd逐渐加1)的存在是为了尽快将丢失的数据包发给目标,从而解决拥塞的根本问题(三次相同的 ACK 导致的快速重传),所以这一过程中 cwnd 反而是逐渐增大的。
以上就是网络拥塞和拥塞控制的四种算法,加油学习