4. 带宽与吞吐量:概念辨析、实际测量方法、常见瓶颈分析

做流控调试这么多年,我见过太多人把带宽和吞吐量混为一谈。有一次排查线上视频会议卡顿,运维说“带宽明明够,100M专线”,结果一测实际吞吐量只有不到2M。嗯,这就是典型的“概念混淆”导致的误判。

说白了,带宽是理论上限,吞吐量是实际表现。你想想看,一条高速公路限速120km/h,但早晚高峰能跑出这个速度吗?网络也是一样的道理。

4.1 概念辨析:带宽 ≠ 吞吐量

维度 带宽(Bandwidth) 吞吐量(Throughput)
定义 链路或设备的理论最大传输速率 实际有效数据传输速率
单位 bps(bit per second) bps,常用Bps(Byte per second)
影响因素 物理介质、调制方式、协议标准 延迟、丢包、协议开销、并发数
典型场景 运营商承诺的“100M宽带” 实际下载文件时的速度
我的经验 买带宽时看这个 调优时盯这个

这里有个关键点:吞吐量永远小于带宽。为什么?因为协议头开销、重传、排队、处理延迟都在“吃掉”有效数据。我曾经在项目中测过一个千兆网卡,实际吞吐量只有600Mbps,查了半天发现是网卡中断合并参数没调好。

核心公式:

有效吞吐量 = 带宽 × (1 - 协议开销率) × (1 - 丢包率) × 并发效率因子

别死记公式,记住一个结论:丢包1%,吞吐量可能下降50%以上。TCP的拥塞控制算法对丢包极其敏感。

4.2 实际测量方法

测量工具我用了十几年,踩过不少坑。下面是我个人习惯的测量方案,分三个层次:

4.2.1 单点吞吐量测试(端到端)

最常用的工具是 iperf3。我建议你把它当成网络调试的“听诊器”。

# 服务端(接收端)
iperf3 -s -p 5201

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

# 参数说明:
# -t 30:测试30秒
# -P 4:4个并行流
# -R:反向测试(测上行)

我的小技巧: 测试时先用单流(不加-P),再用多流。单流能暴露TCP窗口问题,多流能压满带宽。如果单流只有10M,多流能到100M,说明单流窗口限制是瓶颈。

4.2.2 路径吞吐量测量(逐跳)

有时候端到端测出来低,但不知道瓶颈在哪。这时候用 mtr 或 pathchar 逐跳测。

# mtr 结合 ping 和 traceroute
mtr -r -c 100 目标IP

# 重点关注每一跳的丢包率和延迟抖动
# 如果某跳丢包超过1%,那基本就是瓶颈所在

我记得有一次帮客户排查,端到端吞吐量只有5Mbps。用mtr一看,第三跳丢包15%,是个老旧的百兆交换机。换掉之后直接飙到90Mbps。

4.2.3 应用层吞吐量测量

网络层测出来高,不代表应用层体验好。我习惯用 curl 或 wget 模拟真实流量:

# 测HTTP下载速度
curl -o /dev/null -s -w 'Speed: %{speed_download}\n' http://目标文件

# 测TCP连接建立时间
curl -o /dev/null -s -w 'TCP handshake: %{time_connect}s\n' http://目标地址

注意: 应用层吞吐量受协议栈、中间件、应用逻辑影响很大。我曾经遇到一个案例,网络层iperf3能跑满千兆,但应用层HTTP下载只有20Mbps。最后发现是Nginx的worker_connections配得太小,连接被排队了。

4.3 常见瓶颈分析

根据我多年的实战经验,吞吐量瓶颈通常出现在以下几个地方。我画了一张图帮你理清思路:

吞吐量瓶颈分析框架 吞吐量瓶颈 链路层瓶颈 网络层瓶颈 传输层瓶颈 应用层瓶颈 链路层 • 网卡带宽不足 • 双工模式不匹配 • 线缆质量差 • 交换机端口限速 网络层 • 路由环路 • MTU分片 • QoS队列丢弃 • NAT性能不足 传输层 • TCP窗口太小 • 拥塞控制算法 • 连接数限制 • 三次握手延迟 应用层 • 序列化/反序列化 • 业务逻辑耗时 • 数据库查询慢 • 线程池耗尽 排查顺序:链路层 → 网络层 → 传输层 → 应用层 80%的吞吐量问题出在链路层和传输层

4.3.1 链路层瓶颈

  • 带宽不足:最直接的原因。但要注意,运营商说的“100M”是下行,上行通常只有10-20M。
  • 双工模式不匹配:一端全双工,一端半双工,会导致大量冲突和重传。我遇到过交换机自动协商失败,两边都成了半双工,吞吐量直接砍半。
  • 线缆问题:网线过长(超过100米)、水晶头接触不良、光纤弯曲半径太小。这些物理层问题很难排查,但影响巨大。

4.3.2 网络层瓶颈

  • MTU分片:路径MTU小于发送端MTU时,IP分片会导致性能下降。我建议用 ping -M do -s 1472 测试路径MTU。
  • QoS队列丢弃:当流量超过接口带宽时,路由器会丢包。查看接口的discard计数器:show interface | include discard。
  • 路由不对称:去程和回程走不同路径,可能导致TCP的RTT估算不准,影响拥塞控制。

4.3.3 传输层瓶颈

这是我最常遇到问题的层次。TCP的拥塞控制算法对吞吐量影响极大。

TCP算法 适用场景 吞吐量表现 我的建议
Cubic 高带宽、长延迟(数据中心) 优秀 Linux默认,一般不用改
BBR 有丢包的网络(互联网) 极好 强烈推荐,我几乎必开
Reno 低带宽、低延迟 一般 老设备上常见,建议升级
Westwood 无线网络 较好 WiFi场景可以考虑

避坑指南: 我曾经在一个跨国专线项目中,默认Cubic算法只能跑30Mbps,换成BBR后直接飙到200Mbps。原因就是专线有少量丢包(0.5%),Cubic一丢包就减半窗口,BBR基于带宽探测,不受丢包影响。

4.3.4 应用层瓶颈

有时候网络层和传输层都正常,但应用层就是慢。常见原因:

  • 序列化开销:JSON序列化比Protobuf慢5-10倍。高吞吐场景下,这个差距非常明显。
  • 连接复用不足:HTTP/1.1的keep-alive没开好,每次请求都新建TCP连接。我见过一个Java应用,每次请求都new Socket(),吞吐量上不去。
  • 业务逻辑阻塞:同步数据库查询、远程调用等操作阻塞了IO线程。建议用异步非阻塞模型。

重要提醒: 排查吞吐量问题,一定要从底层往上层查。先确认物理链路没问题,再看网络层,然后传输层,最后应用层。跳过底层直接调应用参数,往往是白费力气。

4.4 实战排查清单

最后,我整理了一个排查清单,你可以直接拿去用:

  1. 确认带宽:查看运营商合同、网卡速率(ethtool)、交换机端口速率。
  2. 测端到端吞吐量:用iperf3测,单流和多流都测。
  3. 逐跳排查:用mtr看每一跳的丢包和延迟。
  4. 检查TCP参数:查看窗口大小、拥塞控制算法、是否开启tcp_tw_reuse。
  5. 检查应用层:用curl测HTTP速度,用profiler看业务代码耗时。
  6. 对比测试:换一台机器、换一根网线、换一个端口,排除局部问题。

嗯,这一章的内容就到这里。记住:带宽是广告,吞吐量是疗效。别被运营商忽悠了,动手测一测,你才知道网络到底行不行。