网络基本功:http报文及TCP拥塞控制机制( 三 )


这种情况就叫做拥塞 。拥塞发生的主要原因是网络能够提供的资源不足以满足用户的需求 , 这些资源包括缓存空间、链路带宽容量和中间节点的处理能力 。
由于互联网的设计机制(任何人任何时间都能共享网络资源)导致其缺乏“接纳控制”能力 , 因此在网络资源不足时不能限制用户数量 , 只能靠降低服务质量来继续为用户服务 , 也就是“尽力而为”服务 。但是也不是说增加网络资源 , 就可以避免网络拥塞 。
拥塞虽然是由于网络资源的缺乏引起的 ,  但是单纯增加资源并不能避免拥塞的发生 。有时增加缓存空间到一定程度时 , 只会加重拥塞 , 而不是减轻拥塞 , 这是因为当数据包经过长期时间排队完成转发时 , 他们可能早已经超时 , 从而引起源端超时重发 , 而这些数据包还会继续传输到下一个路由器 , 从而浪费网络资源 , 加重网络拥塞 。事实上 ,  缓存空间不足导致的丢包更多的是拥塞的“症状”而非原因 。
另外 , 增加链路宽带及提高处理能力也不能解决拥塞问题 。
例如我们有4台ABCD主机和一个路由 , 所有的链路带宽都是1Gbps , 如果A和B 同时以1Gbps的速率发送数据 , 则路由器的输入速率为2Gpbs , 从而产生拥塞 。避免拥塞的方法是控制AB的发送速率 , 例如AB都是0.5Gpbs , 但是如果此时D也以1Gpbs的速率发送 , 那么拥塞还是无法避免 , 况且用户主机不可能只有4个 。所以说拥塞只是一个动态问题 , 我们没有办法用一个静态方案去解决 , 从这个意义上说 , 拥塞是不可避免的!!
拥塞是一个全局控制的过程 , 他不像点对点的流控机制 , 是一个局部的控制!
TCP的拥塞控制算法TCP的拥塞控制由4个核心的算法组成: 慢启动(slow start)、拥塞避免(Congestion voidance)、快速重传(Fast Retransmit)和快速恢复(Fast Recovery) 。
拥塞控制 , 在发送方维持着一个拥塞窗口cwmd(congestion window)的状态量 。拥塞窗口的大小取决于网络的拥塞程度 , 并且动态的变化 。发送方让自己的发送窗口等于拥塞窗口 , 另外考虑到接收方的接收能力 , 发送窗口可能小于拥塞窗口 。
4.1、慢启动(slow start)早期的开发的TCP应用在启动一个连接时会向网络中发送大量的数据包 , 这样很容易导致路由器缓存空间耗尽 , 网络发生拥塞 , 使得TCP连接的吞吐量急剧下降 。由于TCP源端一开始并不知道网络资源当前的利用状况 , 因此新建立的TCP连接不能一开始就发送大量的数据 , 而只能逐步增加每次发送的数据量 , 以避免上述现象的发生 。具体来说 , 当新建立一个连接时 , CWND初始化为1个最大报文段(MSS)大小 , 发送端开始按照拥塞窗口大小发送数据 , 每当有一个报文被确认 , cwnd就增加1个MSS大小 。这样cwnd的值就随着网络往返时间(Round trip time , RTT)呈指数级增长 , 事实上 , 慢启动的速度一点也不慢 , 只是他的起点比较低一点儿而已 , 指数级的增长率是十分快的 。
该算法的思想主要是一种探测一下网路的拥塞程度 , 就是不要一开始就发送大量的数据 , 也就是说有小到大逐渐增加(指数)拥塞窗口的大小 。
我们可以简单计算:

  • 开始cwnd=1
  • 经过1个RTT后 ,  cwnd=2*1=2
  • 经过2个RTT后 ,  cwnd=2*2=4
  • 经过3个RTT后 ,  cwnd=2*4=8
  • 如果宽带为W , 那么经过RTT*log2W时间就可以占满带宽;
4.2、拥塞避免(Congestion voidance)如果按上述的慢启动的思想如果不加以控制的话 , 毫无疑问地发生网络拥塞 , 当cwnd很快增长上来的时候 , 也很快利用了网络的资源 , 但是cwnd不能一直这样增长 , 一定需要某个限制 。TCP使用了一个慢启动门限(ssthresh)的变量 , 当cwnd超过该值后 , 慢启动结束 , 进入拥塞避免阶段 。对于大多数的TCP是吸纳来说 , ssthresh的值是65535(同样以16bit来计算) 。拥塞避免的思想就是转指数增大变为加法线性增大 。这样就可以避免增长过快导致网络拥塞 , 慢慢地增加调整到网络的最佳值 。


推荐阅读