3. 吞吐量与带宽:别把马路当流量

带宽和吞吐量,这两个词我见过太多人混着用了。面试的时候一问,十个有八个说「差不多」。其实差远了。

带宽是理论值,是网卡或链路标称的「最大能力」。吞吐量是实际值,是你业务真正能跑过去的数据量。说白了,带宽是高速公路的限速牌,吞吐量是你实际开到目的地的平均速度。

核心区别一句话:带宽是上限,吞吐量是真相。

3.1 带宽 vs 吞吐量:一张表说清楚

维度 带宽 吞吐量
定义 链路或接口的理论最大传输速率 单位时间内实际成功传输的数据量
单位 bps(bit per second) bps 或 Bps(Byte per second)
影响因素 物理介质、调制方式、协议标准 带宽 + 延迟 + 丢包 + 协议栈 + 应用层
典型值 1 Gbps、10 Gbps、100 Gbps 通常为带宽的 60% ~ 95%
谁关心 网络规划、采购 运维、开发、性能优化

我在一次数据中心迁移项目中遇到过一件事:客户买了 10 Gbps 的网卡,上线后监控发现吞吐量只有 2 Gbps。客户直接打电话骂厂商。结果一查,是交换机端口协商成了 1 Gbps,加上 TCP 窗口没调,丢包率 2%。带宽是够的,但吞吐量上不去。嗯,这种坑我踩过不止一次。

3.2 影响吞吐量的三大因素

3.2.1 窗口大小:TCP 的「水龙头」

TCP 窗口大小决定了发送端在收到确认之前能发多少数据。窗口太小,链路就喂不饱。窗口太大,丢包后重传成本也高。

我习惯用 BDP(带宽延迟积)来估算理想窗口:

BDP = 带宽 (bps) × RTT (秒) / 8
# 例如:1 Gbps 链路,RTT = 20 ms
# BDP = 1,000,000,000 × 0.02 / 8 = 2,500,000 字节 ≈ 2.5 MB

如果你的 TCP 窗口只有 64 KB,而 BDP 是 2.5 MB,那吞吐量最多只能用到带宽的 2.5%。你想想看,这浪费有多大。

我的建议:Linux 上直接调大 net.core.rmem_max 和 net.core.wmem_max,然后让 TCP 自动窗口缩放(tcp_window_scaling)接管。别手动写死窗口值,除非你很清楚自己在做什么。

3.2.2 拥塞控制:别把网络挤爆了

拥塞控制算法决定了 TCP 在检测到丢包后怎么降速、怎么恢复。不同的算法对吞吐量的影响天差地别。

  • Cubic:Linux 默认,适合长肥网络(高带宽、高延迟),窗口恢复快。
  • BBR:Google 出品,基于带宽和 RTT 建模,不依赖丢包信号。我在海外 CDN 节点上用过,效果很稳。
  • Reno:老牌算法,丢包后窗口减半,恢复慢。别用了。

我曾经在一条跨国链路上做优化,默认 Cubic 的吞吐量只有 200 Mbps。换成 BBR 后直接飙到 850 Mbps。为什么?因为那条链路上有少量随机丢包,Cubic 误判为拥塞,频繁降速。BBR 不拿丢包当拥塞信号,所以稳住了。

注意:BBR 不是万能的。在丢包率极高的网络里(比如 Wi-Fi 干扰严重),BBR 可能反而导致不公平,挤占其他流的带宽。选算法前先摸清你的网络特征。

3.2.3 丢包:吞吐量的隐形杀手

丢包对吞吐量的影响是指数级的。TCP 一旦检测到丢包,会触发拥塞避免机制,窗口减半,然后慢慢恢复。丢包率每增加 1%,吞吐量可能下降 50% 以上。

我整理了一个经验公式(简化版):

有效吞吐量 ≈ 带宽 × (1 - 丢包率) ^ (1 / 窗口恢复系数)
# 窗口恢复系数取决于拥塞控制算法,Cubic 约 0.7,Reno 约 0.5

举个例子:1 Gbps 链路,丢包率 1%,Cubic 算法:

有效吞吐量 ≈ 1 Gbps × (0.99) ^ (1/0.7) ≈ 1 Gbps × 0.986 ≈ 0.986 Gbps

看起来还好?但如果丢包率到 5%:

有效吞吐量 ≈ 1 Gbps × (0.95) ^ (1/0.7) ≈ 1 Gbps × 0.93 ≈ 0.93 Gbps

实际上,真实环境里丢包还会引发重传超时(RTO),那损失就更大了。我曾经在无线回传链路上见过丢包率 3%,吞吐量直接掉到带宽的 30%。

3.3 吞吐量测试工具:别靠猜,靠测

我见过太多人「我觉得网络没问题」。别觉得,测一下。

3.3.1 iperf3:最趁手的工具

iperf3 是我用得最多的吞吐量测试工具。轻量、跨平台、结果清晰。

基本用法:

# 服务端(先启动)
iperf3 -s -p 5201

# 客户端(发起测试)
iperf3 -c 192.168.1.100 -p 5201 -t 30 -P 4

参数说明:

  • -t 30:测试 30 秒,别只跑几秒,不稳定。
  • -P 4:4 个并行流,模拟多连接场景。
  • -R:反向测试(服务端发数据给客户端),测上行。
  • -w 256K:指定 TCP 窗口大小,配合 BDP 调优时用。

我的习惯:先跑单流(不加 -P),再跑多流。单流能看出单连接的极限,多流能压满带宽。如果单流跑不满,多半是窗口或延迟的问题。

3.3.2 netperf:更细粒度的控制

netperf 比 iperf3 更老,但有些场景它更灵活。比如你想单独测 TCP 请求/响应延迟,或者 UDP 的丢包率,netperf 更顺手。

基本用法:

# 服务端
netserver -p 12865

# 客户端:TCP 流测试
netperf -H 192.168.1.100 -p 12865 -l 30 -t TCP_STREAM

# 客户端:TCP 请求/响应测试(RR)
netperf -H 192.168.1.100 -p 12865 -l 30 -t TCP_RR -- -r 64,1024

-t TCP_RR 测的是请求-响应延迟,-r 64,1024 表示请求 64 字节、响应 1024 字节。这个测试对中间件、代理层特别有用。

3.3.3 工具对比

特性 iperf3 netperf
安装难度 极低(yum/apt 直接装) 中等(需编译或找包)
TCP 流测试 ★★★★★ ★★★★☆
UDP 测试 ★★★★☆ ★★★★★
请求/响应延迟 ★★☆☆☆(需插件) ★★★★★
多流支持 原生 -P 参数 需手动启动多进程
结果可读性 清晰简洁 略复杂

我个人习惯:日常压测用 iperf3,排查延迟和 UDP 场景用 netperf。两个都装,不冲突。

3.4 知识体系:一张图看懂

下面这张图把本章的核心逻辑串起来了。从带宽出发,经过窗口、拥塞控制、丢包三个过滤器,最终得到真实的吞吐量。测试工具就是你的「测量仪」。

吞吐量与带宽核心逻辑图 吞吐量与带宽核心逻辑 带宽(理论上限) 三大影响因素 窗口大小 拥塞控制 丢包 BDP 估算 Cubic / BBR / Reno 重传 + RTO 吞吐量(实际值) iperf3 / netperf 带宽 → 窗口 → 拥塞控制 → 丢包 → 吞吐量,用工具验证每一步

这张图我每次做性能优化培训都会放。你顺着箭头走一遍,就知道问题出在哪一环了。

总结一下:别只看带宽,那是纸面数据。吞吐量才是你的真实体验。窗口、拥塞控制、丢包,这三个点任何一个没调好,带宽再大也是白搭。工具就在手边,测了再说。