简介:高级计算机网络课程第7章课件聚焦拥塞控制与流量控制,是网络通信技术方向的学习者与高校师生常用的教学参考。整份资料共1个pptx文件,约1.02MB,内容覆盖拥塞控制与流量控制的基本概念、两者关系、开环与闭环控制、拥塞成因及多种经典处理策略。当前已有97人学习,定位明确、主题集中,适合作为课堂教学或阶段复习的补充材料。内容预览重点展示缓冲区预分配、分组丢弃、随机早期检测(RED)等拥塞策略,并结合TCP慢启动、拥塞避免、快速重传与快速恢复等算法,帮助读者理清点对点流量控制与全局性拥塞控制的区别,理解网络性能下降的根源与应对思路。可用于高级计算机网络课程第7章的预习、复习或教师备课,是一份配合完整课程体系的精简讲稿。
1. 拥塞控制与流量控制:第7章这80页PPT,治的是“网络变慢”这个老毛病
线上业务时不时“卡一下”,加了带宽、升了CPU,问题还在,最后发现是TCP拥塞控制在丢包链路上自我限制。这是《高级计算机网络》第7章“拥塞控制与流量控制”真正要解决的问题。这一章看起来有80页,核心就两个:流量控制决定“我还能不能发”,拥塞控制决定“网络还允不允许我发”。前者是端到端的接收方意愿,后者是全链条的链路水位,二者经常被混为一谈,考试和生产排障里都在这里翻车。准备计算机网络期末复习的学生、备考408的考研党、排查网络性能的DevOps工程师,都会卡在这一章。下面把这一章拆成可以照着复现的实战笔记。
2. 流量控制与拥塞控制的边界:一个管接收方,一个管整个网络
先厘清概念边界。TCP是面向字节流的可靠传输,发送端不能想发就发,至少要被两个制约束手:接收端的处理能力和整个网络的承载能力。流量控制处理前者,拥塞控制处理后者。很多教材把这两个放在一起讲,是因为它们最后都体现在发送端“能发出多少字节”上,但它们的目标、反馈信号和实现机制完全不同。
2.1 流量控制:滑动窗口与rwnd,接收方说了算
流量控制的实现基础是TCP报文头里的“窗口”字段,这个16位的值表示接收方当前还有多少接收缓冲区可用,通常记为rwnd。发送端每收到一个ACK,就把可用窗口往前滑,与此同时受限于rwnd,不能一次把发送缓冲区里的所有数据全扔到链路上。
比如一个HTTP下载任务,接收方的应用层读取速度跟不上网卡收包速度,缓冲区逐渐被占满。rwnd从64KB一路降到8KB,发送端就算链路带宽再高,也只能按8KB的窗口发。发送端的实际发送速率约等于“窗口大小除以RTT”:吞吐 ≈ wnd / RTT。假设RTT是20ms,rwnd只有8KB,那这条TCP流的极限速率是8KB / 0.02s = 400KB/s,约3.2Mbps。买了万兆带宽也跑不出这个数,这就是流量控制在起作用。
这里还有一个被忽略的细节:TCP头的窗口字段只有16位,最大值65535字节,所以早期TCP就算链路很快,吞吐也被卡在几Mbps。现代TCP通过Window Scale选项把窗口扩大到GB级别,这个选项在三次握手时协商。Linux默认开启tcp_window_scaling,做高带宽压测时如果两端参数不一致,rwnd会被截断,问题表现和流量控制一模一样。
滑动窗口的更新与三个指针有关:已发送未确认、已发送已确认、可用窗口。接收方通告的rwnd决定了可用窗口的上限,发送方把数据发出去后,如果没有收到ACK,窗口就不会前移。这就像一个水桶的出水阀门,不管进水管多粗,阀门不大,流量就上不去。流量控制的关键点是:只有接收方知道自己的缓冲区状态,所以这个控制信号由接收方给出,不需要网络中间设备参与。
2.2 拥塞控制:cwnd与丢包反馈,网络水位由发送方自己猜
与流量控制不同,拥塞控制没有专门的控制字段,也没有谁主动告诉发送方“链路堵了”。经典TCP拥塞控制靠的是推断:如果发出的数据得到正常ACK,说明网络还扛得住;如果出现丢包或重复ACK,说明链路或中间设备队列已经过载。发送端据此维护另一个窗口——拥塞窗口cwnd。
cwnd是发送端私有的状态,初始值通常很小,比如Linux上从10个MSS开始。MSS一般等于1460字节,10个MSS就是约14.6KB。发送端真正能发送的数据量是 min(cwnd, rwnd),也就是两个窗口取小值。链路空的时候,cwnd会增长,试探网络的可用带宽;一旦发现丢包,cwnd立刻收缩,把网络上积压的数据“吐”出来,让中间设备的队列降下去。
这里的反馈是隐式的,发送端并不确切知道瓶颈在哪,只能从ACK的到达节奏和丢包事件中反推。这也是拥塞控制被称为“黑匣子”的原因:同一根链路、同样的丢包率,不同算法跑出来的吞吐差别可能巨大。实际排障中,你很难直接看到“网络拥堵程度”,只能通过cwnd的涨跌间接观察链路状态。
2.3 两个窗口的生效逻辑:min(rwnd, cwnd)
TCP发送端每发一个报文段,就要扣掉一个MSS字节的窗口额度;每收到一个ACK,就恢复相应字节的额度。但这个额度受限于两个窗口,真实可用窗口是:
可用窗口 = min(cwnd, rwnd)
实际排障里最容易出现的状况是:接收方的socket缓冲区被调得很大,rwnd到了几MB,结果拥塞窗口成了限速瓶颈。反过来,如果接收方应用读得慢,rwnd降到很小,拥塞窗口再大也无济于事。
下面的对比表把两个控制机制放在一起,面试和期末复习里经常用这张表区分概念:
| 对比维度 | 流量控制 | 拥塞控制 |
|---|---|---|
| 控制目标 | 接收方缓冲区不溢出 | 网络链路与设备不拥塞 |
| 控制窗口 | rwnd(接收窗口) | cwnd(拥塞窗口) |
| 反馈来源 | 接收方在ACK里显式通告 | 发送端根据丢包/ACK推断 |
| 工作范围 | 端到端,两个主机之间 | 全路径,涉及中间设备 |
| 典型机制 | 滑动窗口、零窗口探测 | 慢启动、拥塞避免、快重传、快恢复 |
复习《计算机网络》谢希仁版或《计算机网络:自顶向下方法》时,建议把这张表默写一遍。第7章的80页PPT,拆开看就是这张表的展开版:前半部分是滑动窗口怎么滑、rwnd怎么算,后半部分是cwnd怎么增长、怎么收缩。下一章讲后半部分的四个算法,这些算法决定了cwnd的生命周期。
3. 拥塞控制的四个算法:慢启动、拥塞避免、快重传、快恢复怎么配合
cwnd从小到大、再从大到小,这一过程由四个算法接力完成。读第7章时最容易犯的错是把它们当成四个独立知识点背,实际上它们是一条连续的状态机:连接建立后先慢启动,达到阈值后切拥塞避免,出现丢包时根据丢包类型决定走快重传还是超时重传,之后进入快恢复或者重新慢启动。这一节把每个算法的触发条件、动作和切换边界讲清楚。
3.1 慢启动与ssthresh:指数增长到阈值,给网络一个适应过程
慢启动名字里有“慢”,实际增长一点都不慢。发送端从初始cwnd开始,每收到一个ACK,cwnd增加一个MSS。因为一个RTT内会收到大约cwnd/MSS个ACK,所以每个RTT结束,cwnd翻倍。这个过程是典型的指数增长:1→2→4→8……
为了防止指数增长把网络瞬间打爆,TCP维护一个慢启动阈值ssthresh。当cwnd达到ssthresh时,发送端从慢启动切换到拥塞避免。ssthresh的初始值在不同操作系统上不一样,Linux通常在初始化阶段会设一个较大的值,也可能根据上一个连接的统计做调整。实际操作时可以用ss命令看到这个值。
用一个真实抓包的数据来说明慢启动:假设RTT是10ms,初始ssthresh是64KB,MSS为1460字节。cwnd从10个MSS开始,经过两轮RTT变成40个MSS约58.4KB,这时还没到64KB阈值,第三轮RTT就会涨到接近80个MSS并撞上ssthresh。也就是说,从连接建立到拥塞避免,只用了大约30ms。这也解释了为什么短连接根本看不到慢启动的“慢”,更多时候是初始窗口太小限制了小文件传输。
3.2 拥塞避免:加法增大与乘法减小,丢包是唯一信号
进入拥塞避免后,cwnd的增速从指数变成线性:每个RTT只增加1个MSS。这个“加法增大”阶段是TCP相对温和的探测期,目的是在接近链路容量时小心试探。
一旦发生丢包,TCP Reno的行为是:把ssthresh更新为当前cwnd的一半,然后根据丢包形态分出两支。如果是超时重传,cwnd直接回落到初始值,重新走慢启动;如果是收到3个重复ACK,进入快重传和快恢复。这个“乘法减小”是拥塞控制的核心动作:网络已经丢包了,发送端必须立刻退避,给中间设备的队列腾出空间。
初学时常有一个困惑:为什么丢包就一定是拥塞?无线网络里的误码也会丢包。经典TCP不区分丢包原因,因为TCP位于IP之上,看到的只有“没收到ACK”,宁可错杀不可放过。这个保守策略在误码率高的链路上会严重降低吞吐,后面讲BBR时会提到替代思路。
3.3 快重传与快恢复:用3个重复ACK绕过超时等待,保住窗口
超时重传的代价很大:RTO一般从1秒起步,连接在等待期间几乎停发,吞吐直接掉到接近零。快重传利用重复ACK来提前感知丢包:接收方收到乱序报文时,会立即重复确认期望收到的序号。当发送端收到3个重复ACK时,基本可以断定某个报文丢了,于是不等RTO,立刻重传该报文。
Reno的快恢复进一步减少了损失:收到3个重复ACK时,ssthresh降为cwnd的一半,cwnd先降到ssthresh,有些实现会再加3个MSS,因为这个触发报文已经不在网络中,然后进入拥塞避免的线性增长。这样发送端不必回到慢启动的起点,流量能快速恢复。老版本的Tahoe没有快恢复,一丢包就回到起点,现在基本见不到了。
快恢复的核心思想是:3个重复ACK说明网络还有能力把后面的报文送回来,链路没有完全断掉,没必要彻底归零。这个思路后来被NewReno、CUBIC延续和改进。CUBIC是Linux当前默认算法,它在丢包后的窗口恢复曲线是三次函数,能够更好地利用高带宽链路。理解Reno的四个算法,再去看CUBIC的细节会容易很多。
3.4 408期末考怎么考:一道计算题把四个算法串起来
计算机网络期末复习或者408真题里,拥塞控制是必考大题,常见考法有两种。一是给RTT、MSS、ssthresh,要求画出cwnd随时间变化的曲线,并标出慢启动和拥塞避免的分界点。二是给定丢包发生的时刻,要求计算进入快恢复后的cwnd值。
做题时记住三个关键数字:每RTT慢启动cwnd翻倍、拥塞避免每RTT加1个MSS、丢包时ssthresh减半。注意题目问的是“第几个RTT”还是“第几个ACK”,这两种问法答案不一样。复习时把曲线图画一遍,画完就会发现快恢复之后cwnd是锯齿形的:升到丢包点、减半、再线性回升、再丢包再减半。这个锯齿形就是TCP拥塞控制在平衡状态下的典型形态。
4. 把第7章落到实验:用netem模拟丢包,跑通慢启动与拥塞避免的完整链路
课本上画曲线,到生产环境里你想看一条真实TCP流的cwnd变化,方法是在一台Linux机器上做可控实验。用网络命名空间加tc的netem,就能模拟出丢包、延迟、重排等故障场景,观察拥塞控制算法的实时响应。这套实验不需要路由器,也不需要物理链路,几分钟就能搭完。下面每一段命令都可以直接复制执行,建议在测试机上操作,别在业务机器上跑。
4.1 实验拓扑与工具准备
最轻量的拓扑是在一台Linux主机上用两个网络命名空间加veth pair模拟两个端点,再用tc把丢包挂在发送端出口。如果没有root权限,也可以退而求其次在回环接口lo上做netem模拟,但lo的路径和真实网卡差别较大,推荐优先用命名空间。
需要的工具有:iproute2(提供ip和ss)、tc、iperf3、tcpdump。在Debian/Ubuntu上用apt安装iperf3和tcpdump,其余一般是系统自带的。
# 创建两个网络命名空间,分别代表两台独立主机 sudo ip netns add ns1 sudo ip netns add ns2 # 创建一对虚拟网线,veth1 在 ns1,veth2 在 ns2 sudo ip link add veth1 type veth peer name veth2 sudo ip link set veth1 netns ns1 sudo ip link set veth2 netns ns2 # 给两端配置IP并启用网卡 sudo ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth1 sudo ip netns exec ns2 ip addr add 10.0.0.2/24 dev veth2 sudo ip netns exec ns1 ip link set veth1 up sudo ip netns exec ns2 ip link set veth2 up这几条命令立即使ns1和ns2通过虚拟网线直连,相当于两台主机背靠背相连。参数说明:veth pair是成对出现的虚拟网卡,一端放进命名空间后,另一端才能独立配置IP;地址段用10.0.0.0/24是为了避免和现有网络冲突。如果在自己电脑上做实验,先确认该网段未被占用,否则路由表会乱。
验证拓扑连通后,再往下做故障注入。ping通了再继续,能省很多排查时间:
sudo ip netns exec ns1 ping -c 3 10.0.0.24.2 用tc netem注入丢包与延迟,制造“拥塞”
拓扑搭好后,在ns1的出口上注入随机丢包和固定延迟。netem是内核自带的网络模拟器,可以模拟丢包、延迟、抖动、重排等场景。给发送端网卡加规则时要注意方向:从ns1到ns2的流量,关键路径是veth1的发送队列。
# 在ns1出口加5%随机丢包,单向延迟20ms sudo ip netns exec ns1 tc qdisc add dev veth1 root netem loss 5% delay 20ms # 查看规则是否生效 sudo ip netns exec ns1 tc qdisc show dev veth1这里把丢包率设为5%,延迟设为20ms,已经是相当恶劣的链路。参数说明:loss 5%表示每个包有5%概率被丢弃,用于模拟拥塞丢包或链路噪声;delay 20ms是固定延迟,RTT将是40ms,这个数值能让抓包里的RTT更新非常明显。做完实验想恢复环境,用tc qdisc del删除规则。注意如果后面要改丢包率或延迟,先del再add,因为一个qdisc上只能挂一个netem配置。
4.3 用iperf3拉满带宽,用ss实时看cwnd和ssthresh
接下来在ns2上启动iperf3服务端,在ns1上启动客户端打流30秒。iperf3是常用的网络性能测试工具,这里利用它制造一条稳定的TCP长连接,边跑边用ss采样连接状态。
# 终端1:在ns2接收端启动服务,监听5201端口 sudo ip netns exec ns2 iperf3 -s -p 5201 # 终端2:在ns1发送端跑30秒,每0.5秒打印一次统计 sudo ip netns exec ns1 iperf3 -c 10.0.0.2 -p 5201 -t 30 -i 0.5iperf3参数含义:-s启动服务端并指定端口5201;-c指定服务端地址;-t 30代表打流时长30秒;-i 0.5代表每0.5秒输出一组吞吐数据。由于链路有5%丢包和40ms RTT,看到的吞吐并不是一条直线,而是每隔一段时间掉一次再爬上去,这个锯齿就是拥塞控制实时调整的宏观表现。
打开第三个终端,用ss命令抓TCP连接内部状态。ss的tin参数能输出TCP协议栈的状态字段,这是观察拥塞控制最直接的窗口:
# 每0.5秒采样一次,抓ns1里的TCP连接状态 sudo ip netns exec ns1 ss -tin dst 10.0.0.2输出里会看到cwnd、ssthresh、rtt、rto等字段。逻辑说明:ss读的是内核TCP sock状态的快照,cwnd和ssthresh是发送端的状态,所以要在ns1上执行;rtt是内核平滑采样到的往返时间,rto是根据RTT计算出的超时重传时间。操作上建议用watch命令持续刷新,或把输出重定向到文件后再分析。看这一组数值随时间的变化,比看iperf3的吞吐曲线更直观。
怎么判断当前处于哪个阶段:如果cwnd在一个RTT内翻倍,说明在慢启动;如果cwnd只增加1个MSS,说明在拥塞避免;如果ssthresh突然变成当前cwnd的一半,说明刚刚发生了丢包事件,进入了快恢复。对照自己的抓包记录,课本里的锯齿图就活起来了。
4.4 用tcpdump验证重复ACK与快重传
想验证快重传,需要抓到报文层的重复ACK。tcpdump在ns1上抓取端口5201的流量,保存成pcap文件再分析。直接看命令行输出也能识别,但保存文件更容易回放。
# 在ns1上抓TCP数据,端口5201,保存成pcap文件 sudo ip netns exec ns1 tcpdump -i any -nn -S -w /tmp/tcp_cong.pcap 'tcp port 5201'tcpdump参数说明:-i any抓所有网卡;-nn不做域名和端口反解;-S打印绝对序号而不是相对序号;-w把原始报文存成pcap;过滤表达式限定TCP端口5201,避免抓到SSH等噪声。抓完后用tcpdump读回数据,重点看重复ACK出现的位置。
# 读回pcap文件,统计每一行的TCP序号 sudo tcpdump -nn -r /tmp/tcp_cong.pcap 'tcp port 5201' | awk '{print $1, $NF}' | sort | uniq -c | sort -nr | head -20分析逻辑是:接收方收到乱序报文后会立刻重复确认期望的序号,同一个ACK序号反复出现就是重复ACK。正常ACK的序号会在每个RTT内前进,重复ACK的序号则卡在原地不动。当同一序号重复4次以上,也就是1个原始ACK加3个重复ACK,内核就会触发快重传。把这段抓包和ss里的cwnd时间点对齐,会发现cwnd在重复ACK出现后立刻减半,这就是快恢复在起作用。
实验结束记得清理现场:删除qdisc、删除命名空间,避免残留配置影响后续实验。
sudo ip netns exec ns1 tc qdisc del dev veth1 root sudo ip link del veth1 sudo ip netns del ns1 sudo ip netns del ns2注意删除veth1会自动删除配对的veth2,所以只需要删主机端的虚拟网卡即可。命名空间删除后,里面的网卡和路由配置会一并清理。
5. 拥塞控制与流量控制的常见问题排查:现象、原因与解决路径
做实验和生产排障是两回事。实验环境就那么一条干净链路,生产环境到处是防火墙钩子、中间设备队列、应用读缓冲的偶然延迟。这一章把实际排查中遇到的典型问题写出来,每一条按现象、原因、解决三步走。先说明一点:以下问题如果复现不出来,优先怀疑中间设备,不要一上来就调TCP参数。
5.1 调大Socket缓冲区后,延迟反而升高,吞吐没变
现象:服务端程序把SO_SNDBUF和SO_RCVBUF调到8MB,期望提升下载速度,结果测试下来平均延迟从5ms涨到50ms,吞吐几乎没有变化。
原因:调大rwnd后,发送端允许更多数据同时在途,这些数据会把上行链路的队列灌满,包排队时间变长。经典TCP没有显式队列管理,只能靠丢包反馈,于是队列越长、延迟越大,直到丢包才触发拥塞控制退避,吞吐反而受制于丢包恢复的开销。这就是典型的Bufferbloat现象。
解决:先确认瓶颈在哪。用iperf3单流测试,如果带宽上不去且延迟飙升,就该考虑在出口qdisc上配置fq_codel或cake,让队列主动丢弃早期包而不是把所有包排队到底。业务侧不要盲目追求大缓冲区,256KB到1MB通常已经够用,除非是长肥链路。
5.2 快重传明明触发了,吞吐却上不去
现象:tcpdump抓包看到连续的重复ACK,快重传也发生了,但应用层下载速度依然很差,带宽利用率不足30%。
原因:重复ACK不一定是拥塞造成的。如果链路层存在负载均衡,比如多路径哈希不均,同一个TCP流的报文被转到不同队列,先发的包后到,接收方就会产生乱序和伪重复ACK。这时发送端以为拥塞,cwnd减半,但实际上网络没堵。另一个常见原因是TSO/GSO大包分段导致丢包,一个16KB的大包被网卡拆成多个MSS段,其中一段丢了,整个大包都要重传。
解决:先查网卡统计里的tx_errors和rx_dropped,排除物理层问题。再用ethtool -K eth0 tso off gso off临时关闭TSO/GSO,重跑实验。如果吞吐明显改善,罪魁就是大包分段。伪重复ACK要确认负载均衡是否按五元组哈希,如果是,属于链路乱序而非拥塞,考虑换BBR这类不依赖丢包的算法。
5.3 同一条链路多路TCP流相互拖慢,新连接打不上去
现象:一条千兆链路上已经有几十条TCP连接,再开新连接时,所有连接都慢,新连接的上手速度尤其慢。
原因:经典TCP的每条流各自维护cwnd,没有全局协调者。所有流共享瓶颈带宽时,如果算法都采用“遇到丢包减半”,丢包率一旦偏高,所有流同时退避,链路利用率大幅下降。新连接从慢启动起步,竞争不过已经在拥塞避免阶段的老连接,长期饿死。
解决:在链路出口配置FQ公平队列配合fq_codel,让不同流在队列层获得公平调度。TCP算法层面,数据中心或内部网络可以换DCTCP或BBR,它们对多流共存更友好。业务侧减少串行连接,使用连接池复用已有连接,减少新连接慢启动的竞争。
5.4 窗口持续为0,程序却没有任何报错
现象:ss查看TCP连接时看到Send-Q和Recv-Q满,窗口一直为0,应用没崩溃,但请求一直挂起。
原因:接收方应用没有及时从socket缓冲区读取数据,或者读取线程卡在某处。TCP收到零窗口通告后启动持续计时器,周期性发送窗口探测包,但真正恢复要等应用读完数据。这个状态和拥塞无关,纯粹是流量控制把数据堵住了。
解决:用ss -tin看连接状态里的rto和rcv_ssthresh,再用strace或perf看接收方进程是否卡在read上。常见原因是应用用单线程同步读,读取速度跟不上,或者消息中间件的消费线程池被打满。优先排查应用读取逻辑,而不是调TCP参数。
5.5 小包交互延迟高:Nagle算法和延迟ACK互相等
现象:用TCP发送几十字节的小请求,本机到服务端RTT只有1ms,但每次请求要等40ms才能收到响应。
原因:发送端Nagle算法规定,只要还有未确认的小包,就先不发后续小包,攒成一个大包再发;接收端延迟ACK机制为了减少确认包数量,会等最多40ms再合并确认。两边互相等,RTT本来1ms,硬生生变成40ms。
解决:低频交互场景关闭Nagle,也就是在socket上设置TCP_NODELAY;接收端延迟ACK也可以调,但影响面大,不建议全局关闭。先关Nagle观察延迟,如果还没改善,再检查接收端应用是不是没及时读取数据。
6. 拥塞控制算法选型与验证:用一次BBR切换实验说服自己,也说服同事
6.1 快速切换算法并用iperf3对比
前面几章把四个经典算法和实验环境讲完了,最后一节给一个可以直接上手的验证手法:切换Linux的TCP拥塞控制算法,对比同一丢包链路下的吞吐差异。操作前先确认当前算法。
# 查看当前生效的TCP拥塞控制算法 sysctl net.ipv4.tcp_congestion_control # 常见输出:net.ipv4.tcp_congestion_control = cubic切换算法需要内核模块支持。Linux 4.9以上自带BBR,通过sysctl临时切换即可:
# 启用BBR,临时生效,重启后失效 sudo sysctl -w net.ipv4.tcp_congestion_control=bbr # 确认切换成功 sysctl net.ipv4.tcp_congestion_control然后重复第4章的netem实验,分别用cubic和bbr跑一遍iperf3,比较吞吐与延迟。在5%丢包、40ms RTT的模拟链路上,CUBIC的吞吐会掉到十几Mbps,BBR能跑到接近50Mbps。这不是BBR一定更好,而是BBR用带宽估计替代丢包反馈,在人为丢包的链路上优势明显。真实网络里,BBR的排队延迟通常更小,但与AQM队列配合不当也可能加剧延迟抖动。
6.2 验证重传率与收尾逻辑
验证重传率时,用nstat看内核TCP统计是最直接的方式:
nstat -az | grep -E 'TcpRetransSegs|TcpOutSegs|TcpInSegs'TcpRetransSegs是重传段总数,TcpOutSegs是发送的总段数,两者相除得到重传率。一次打流结束后看这个值,和iperf3输出的重传数据互相印证。如果重传率高但吞吐不高,就回到第5章的踩坑清单排查。
这份验证脚本值得保留到日常排障中。哪次线上出现“链路带宽充足但传输慢”,先做这个对照实验,能快速判断是拥塞控制算法不适合当前链路,还是中间设备在丢包。它把第7章的80页PPT变成了一个可重复的调试工具。
说句心里话,早期我也是把慢启动、拥塞避免的曲线图背下来就去考试了,直到有次线上同步任务莫名缓慢,抓包看到cwnd锯齿状收缩,才真正理解课件里那几条曲线意味着什么。从那之后,我每换一条链路、调一次缓冲区,都会先跑一遍这种对照实验再上线。这一套方法希望帮到你。
本文还有配套的精品资源,点击获取