服务器带宽的独享和共享到底差在哪?从原理到实测讲清楚
一、从一个问题说起
服务器带宽标称100M,白天iperf跑出来99M,没问题。
但用户反馈每天晚上七八点以后网站特别慢。
查服务器CPU、内存、负载,全正常。Nginx日志没有异常。应用层没有任何问题。
然后让运维跑了一下iperf:
bash
# 晚上8点
iperf3 -c 公共测试IP -t 30 -P 4
css
[ ID] Interval Transfer Bitrate
[ 5] 0.00-30.00 sec 42.5 GBytes 12.2 Mbits/sec
100M带宽只跑出12M。
第二天凌晨再测:
bash
# 凌晨2点
iperf3 -c 公共测试IP -t 30 -P 4
css
[ ID] Interval Transfer Bitrate
[ 5] 0.00-30.00 sec 348 GBytes 99.7 Mbits/sec
跑满了。
同一个服务器,同一条线路,凌晨100M,晚上12M。
这种"白天正常晚上慢"的带宽表现,根因通常是共享带宽。
二、独享和共享的技术本质
独享带宽
服务器接入的物理链路带宽全部分配给你。不存在和其他用户争抢的问题。
css
[你的服务器] ──── 100Mbps专线 ──── [核心交换机] ──── [互联网]
不管什么时段,这条100M线路都是你的。实际速率受限于物理链路能力,不会因为别人的流量而缩水。
共享带宽
服务器接入的是一个大带宽池,你和其他用户共同使用。
css
[你的服务器] ──┐
[用户A] ──┤
[用户B] ──┼── 1Gbps总线路 ──── [核心交换机] ──── [互联网]
[用户C] ──┤
[用户D] ──┘
假设总线路1Gbps,分给20个客户,每家"100M"。理论上20家同时跑满刚好用完1G。
但实际上不是所有人同时跑满。白天大多数人访问量不大,总带宽有富余,你偶尔能跑满100M。但到了晚上,大家都在线,20家一起抢1G,每家实际分到的就少了。
共享带宽用的是统计复用(Statistical Multiplexing)的思路: 假设所有用户不会同时用满带宽,所以在总带宽不变的情况下分配了超过总带宽的承诺。这在大部分时候是成立的------大部分服务器大部分时间用不满带宽。但一旦出现所有用户同时高负载的场景,承诺的带宽就兑现不了了。
三、怎么辨别:iperf不同时段测试
最直接的方法:不同时段跑iperf看差异。
bash
# 找一台独享带宽的测试服务器(各大云厂商通常有公共iperf节点)
# 或者用 iperf.he.net / bouygues.iperf.fr 等公共节点
# 不同时段各跑一次
iperf3 -c 测试IP -t 30 -P 4
写个脚本自动记录:
bash
#!/bin/bash
# save as bandwidth_test.sh
# crontab: 不同时间执行,比如 0 2,10,14,20,22 * * *
TEST_IP="你的测试IP"
LOG_FILE="/var/log/bandwidth_test.log"
echo "=== $(date '+%Y-%m-%d %H:%M:%S') ===" >> $LOG_FILE
iperf3 -c $TEST_IP -t 30 -P 4 2>&1 | grep "sender" >> $LOG_FILE
echo "" >> $LOG_FILE
bash
# 加到crontab,每天不同时段各跑一次
crontab -e
javascript
0 2 * * * /root/bandwidth_test.sh
0 10 * * * /root/bandwidth_test.sh
0 14 * * * /root/bandwidth_test.sh
0 20 * * * /root/bandwidth_test.sh
0 22 * * * /root/bandwidth_test.sh
跑几天之后看数据:
ini
=== 2024-12-01 02:00:00 ===
[ 5] 0.00-30.00 sec 348 GBytes 99.7 Mbits/sec
=== 2024-12-01 10:00:00 ===
[ 5] 0.00-30.00 sec 238 GBytes 68.5 Mbits/sec
=== 2024-12-01 14:00:00 ===
[ 5] 0.00-30.00 sec 192 GBytes 55.2 Mbits/sec
=== 2024-12-01 20:00:00 ===
[ 5] 0.00-30.00 sec 42.5 GBytes 12.2 Mbits/sec
=== 2024-12-01 22:00:00 ===
[ 5] 0.00-30.00 sec 65.0 GBytes 18.7 Mbits/sec
判断标准:
- 凌晨和晚高峰差距 < 10% → 独享
- 差距 10%-30% → 不确定,可能共享也可能有其他原因
- 差距 > 30% → 大概率是共享带宽
四、上行和下行可能不一样
除了独享/共享,还有一个容易忽略的问题:上下行速率是否对称。
对Web服务器来说:
- 上行(服务器往外发)= 用户下载页面、图片、API响应
- 下行(服务器接收)= 用户上传文件、发送请求
大部分Web业务,上行流量远大于下行。上行才是瓶颈。
有些带宽方案是不对称的:
bash
# 测上行(默认方向:客户端发给服务端)
iperf3 -c 测试IP -t 10
# 测下行(-R反转:服务端发给客户端)
iperf3 -c 测试IP -t 10 -R
如果两个数字差距很大,说明上下行不对称。对Web服务来说,要重点关注上行那个数字。
对称的线路两个方向的速率应该基本一致(差距 < 10%)。
五、一个完整的带宽排查流程
遇到"带宽跑不满"或者"高峰期网速慢"的问题,按这个顺序排查:
Step 1:确认网卡和线路物理状态
bash
# 看网卡协商速率
ethtool eth0 | grep Speed
# Speed: 1000Mb/s ← 千兆网卡,正常
如果是 Speed: 100Mb/s,说明网卡协商到了百兆,可能网线或者交换机端口有问题。
bash
# 看网卡错误统计
ethtool -S eth0 | grep -i "error\|drop"
rx_errors、tx_errors、rx_dropped如果有持续增长,说明物理层有问题。
Step 2:iperf测实际带宽
bash
iperf3 -c 测试IP -t 30 -P 4
-P 4 表示4个并发流,避免单流被TCP窗口限制。如果带宽很大(>1G),可能需要更多并发流。
如果iperf跑出来的速率远低于标称带宽,问题在链路层。如果iperf能跑满但业务访问慢,问题在应用层。
Step 3:不同时段对比
用上面的脚本跑几天,看是否有时段性波动。
Step 4:检查TCP拥塞控制
如果iperf跑不到标称带宽,排除了共享因素后,检查TCP拥塞控制算法:
bash
sysctl net.ipv4.tcp_congestion_control
# cubic
在跨网场景下CUBIC可能只能用到带宽的30-50%。换成BBR试试:
bash
sysctl -w net.ipv4.tcp_congestion_control=bbr
sysctl -w net.core.default_qdisc=fq
切换后重新iperf测试。如果带宽利用率明显提升,说明之前的瓶颈在拥塞控制算法。
Step 5:检查TCP缓冲区
bash
sysctl net.ipv4.tcp_rmem
sysctl net.ipv4.tcp_wmem
ini
net.ipv4.tcp_rmem = 4096 87380 6291456
net.ipv4.tcp_wmem = 4096 65536 6291456
第三个数字是最大缓冲区大小。高延迟场景下,带宽时延积(BDP)= 带宽 × 延迟。如果缓冲区最大值小于BDP,带宽会被缓冲区限制。
bash
# 例:100M带宽,100ms延迟
# BDP = 100Mbps × 100ms = 1.25MB = 1,250,000字节
# 如果tcp_wmem最大值只有6MB,对这个场景够用
# 但如果带宽更大或延迟更高,可能需要调大
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
Step 6:确认不是应用层瓶颈
bash
# 看Nginx的实际传输速率
# 开启access_log的$body_bytes_sent和$request_time
tail -f /var/log/nginx/access.log | awk '{print $NF, $(NF-1)}'
如果Nginx的传输速率远低于iperf测出来的带宽,说明瓶颈在应用层(Nginx配置、后端处理、磁盘IO等),不在网络层。
六、关于BGP线路的带宽
BGP多线的带宽情况更复杂一些。"100M BGP"可能有几种含义:
css
含义A:电+联+移 总共100M(三线共享总量)
含义B:每条线路各100M(每线独立)
含义C:总出口100M,BGP只负责智能选路(选哪条线路出去,但总量不变)
这几种情况下实际可用带宽差距很大。拿到BGP线路后,分别从不同运营商的节点iperf测试:
bash
# 从电节点测
iperf3 -c 服务器电信IP -t 30
# 从联节点测
iperf3 -c 服务器联通IP -t 30
如果电跑满的同时联通也跑满了,说明每线独立。如果电信跑满时联只有三分之一,说明总量共享。
七、总结
遇到带宽相关的问题,核心排查思路就一条线:
markdown
物理层正常吗?(网卡速率、错误统计)
→ 正常 → iperf能跑满吗?
→ 能 → 问题在应用层,查Nginx/后端
→ 不能 → 不同时段有差异吗?
→ 有差异 → 大概率是共享带宽
→ 无差异 → 查TCP拥塞控制和缓冲区
iperf是最基础的工具。拿到服务器后第一时间不同时段跑几次iperf,对自己的带宽情况心里有数。别等业务出问题了才去测。
TCP调优(换BBR、调缓冲区)能解决不少"带宽跑不满"的问题。特别是跨网场景下,CUBIC和BBR的差距非常大。
如果是共享带宽导致的高峰期缩水,TCP调优帮不了------瓶颈不在TCP层,在物理链路的总容量。这种情况要么接受,要么换独享线路。