网络设计第八问:拥塞控制------慢启动、拥塞避免、快重传
流量控制是接收方说了算。拥塞控制是发送方自己估------根据丢包、RTT------猜"现在网络中能承受多少数据"。这个猜难在哪里?你不知道中间路由器的缓冲区大小。而这个大小随每一次拥堵而变。
文章目录
- 网络设计第八问:拥塞控制------慢启动、拥塞避免、快重传
-
- 一、为什么需要拥塞控制
- 二、慢启动------不是你想象的那样
- [三、拥塞避免------每 RTT 加 1](#三、拥塞避免——每 RTT 加 1)
- [四、丢包 ≠ 拥塞](#四、丢包 ≠ 拥塞)
- 五、社保系统里的现实
一、为什么需要拥塞控制
发送方拼命发------路由器排队------缓冲区满了------丢包------丢包触发重传------全网都是重传包------有效吞吐跌到零。这不是接收方的问题------是网络链路本身承载不了。
拥塞控制不给发送方一个固定的上限------它根据当前网络的拥塞情况------动态调整发送速率。丢包了→减小速率。没丢包→慢慢增大速率。
二、慢启动------不是你想象的那样
慢启动不是慢------是指数增长。开始窗口=1个 MSS(最大报文段长)------收到一个 ACK→窗口+1------窗口从 1→2→4→8→16→...------每 RTT 翻一倍。
为什么叫"慢"?不是增速慢------是起点小。正常窗口可能几百或几千------慢启动从 1 开始------虽然增长快------但初始值低------总体在前期是保守的。
阈值------当窗口超过 ssthresh------从慢启动切换为拥塞避免------线性增长。
三、拥塞避免------每 RTT 加 1
持续增加窗口直到丢包------窗口每 RTT 增加 1 个 MSS------增速平缓------避免突然冲垮网络------但也不能断掉------持续在网络容量边缘试探。
当检测到丢包------两种处理:
- 超时重传(RTO)------很可能发生了严重拥塞------把 ssthresh 设为当前窗口的一半------窗口退回 1------重新开始慢启动
- 快重传(3个重复ACK)------后面三个包到了------中间一个丢了------阻塞程度不严重------ssthresh=窗口/2------窗口=ssthresh+3------直接进入拥塞避免------不重新慢启动
四、丢包 ≠ 拥塞
现代网络更复杂------一个 Wi-Fi 干扰丢包------信号层问题------不是链路满------而传统 TCP 把它当拥塞------窗口减半------吞吐白跌。
BRR 基于 RTT 而非丢包------RTT 开始变大→缓冲区在满的边缘→开始减速------不等丢包。比丢包信号更精确------在 Wi-Fi 和卫星链路等误码高的环境下------BRR 不白减速。
五、社保系统里的现实
社保结算平台到银行之间的链路------RTT 15ms------带宽 100Mbps------丢包率极低。拥塞控制在这个链路上几乎不被触发------因为队列从不溢出。真正的瓶颈不是拥塞------是应用层串行的多次查询------改批处理才解决问题------不是调 TCP 参数。
但社保到外部系统的专线------经过运营商的 MPLS VPN------共享链路------可能某个其他客户的业务高峰期------路由器的队列满了------你的重传开始上升。你看到的不是页面慢------是 TCP 窗口闪降。而你能做的只是在应用层加超时和告警------你不能控制运营商的队列策略。
✅ 亮点:从慢启动的指数增长逻辑出发,拆开超时重传(严重)和快重传(中等)两种丢包响应的区别,用社保-银行专线讲链路稳定时拥塞控制不生效的情况。扩展方向:BBR 的非丢包拥塞检测、QUIC 的拥塞控制与 TCP 的差异。