服务器带宽没有跑满,为什么单连接下载速度仍然很低
服务器端口带宽没有跑满,并不代表单连接下载一定快。本文从 RTT、丢包、TCP 窗口、拥塞控制、客户端与服务端性能出发,解释总带宽、单连接速度和多连接吞吐为什么会不同,并说明 curl、wget、iperf3 各自适合看什么。
既然带宽还有大量空余,为什么下载速度就是上不去?
这类问题很容易被误判为“机房限速”或者“服务器带宽虚标”。但在实际排查中,服务器总带宽没有跑满,只能说明出口仍有剩余,并不能证明某一个 TCP 连接可以把剩余带宽全部利用起来。
一个看似矛盾的香港服务器下载故障
这次测试使用的是一台香港服务器,配置如下:
Intel Xeon E-2334
32GB 内存
960GB NVMe SSD
100Mbps BGP 带宽
Debian 12 系统
Nginx 提供静态文件下载
服务器中放置了一个 5GB 测试文件。广东电信用户通过浏览器下载,速度基本稳定在 900KB/s~1.3MB/s,偶尔会短暂升到 2MB/s,但很快又掉下来。
按照理论换算:
100Mbps ÷ 8 = 12.5MB/s
考虑 TCP、HTTPS、以太网封装等协议开销,100Mbps 带宽实际下载速度达到 10MB/s~11.5MB/s 都是正常的。
但这里单连接只有约 1MB/s,相当于只用了不到 10Mbps。
服务器监控也显示,网卡总发送流量只有十几 Mbps。于是问题出现了:既然服务器还有八九十 Mbps 空余,为什么这个下载连接不能继续提速?
先增加连接数,结果暴露了真正的问题
我们没有立即调整 Nginx,也没有直接联系机房,而是先让同一台客户端使用多线程下载工具测试。
单线程下载结果:
平均速度:1.1MB/s
开启 8 个并发连接后:
平均总速度:9.6MB/s
这个结果非常关键。
如果服务器硬盘读取能力不足、网卡被限制在 10Mbps,或者整个服务器出口被限速,多连接下载通常也无法达到接近 10MB/s。现在 8 个连接可以把速度提升到 9.6MB/s,说明服务器带宽、磁盘和 Web 服务整体都具备接近 100Mbps 的输出能力。
问题并不是“服务器总带宽不够”,而是“单个 TCP 连接无法充分利用带宽”。
这也是很多香港服务器下载问题最容易被忽略的区别。
带宽空闲,不代表单连接可以无限加速
互联网下载并不是服务器看到出口有空余,就不断把数据塞给客户端。
一个 TCP 连接能够发送多少数据,会受到接收窗口、拥塞窗口、往返延迟和丢包情况共同影响。服务器每发送一批数据,都需要根据客户端返回的确认信息,判断是否可以继续扩大传输规模。
香港到中国大陆虽然地理距离不远,但不同运营商、不同线路的实际往返延迟差异很大。
例如:
广东到香港优化线路:10ms~25ms
华东到香港普通国际线路:35ms~60ms
北方到香港绕路线路:60ms~100ms
当延迟升高时,数据包发送后需要更长时间才能收到确认。如果 TCP 窗口没有相应增大,连接就会频繁出现“已经发出的数据还没确认,暂时不能继续发送”的状态。
可以把它理解成一条运输线路。
服务器带宽代表高速公路有多宽,TCP 窗口则代表同时允许多少辆货车上路。即使高速公路有十条车道,如果规则限制一次只能放几辆车进入,整条路看起来仍然很空。
以 100Mbps 带宽、50ms 往返延迟为例,要持续跑满线路,理论上至少需要约 625KB 的有效传输窗口:
100Mbps × 0.05 秒 ÷ 8 ≈ 625KB
如果中间经过代理、旧版本系统、异常内核参数或限制较小的应用程序缓冲区,使单连接有效窗口只有 64KB,那么这个连接就很难接近 100Mbps。
现代 Linux 通常支持 TCP Window Scaling,并会自动调整缓冲区,因此正常情况下不需要手动设置一个固定窗口。但如果系统参数被优化脚本错误修改,或者客户端、代理设备不支持窗口扩展,单连接速度仍然可能受到明显限制。
真正拉低速度的,往往是那一点点丢包
继续查看这条连接的路由质量后,我们发现平均延迟约为 48ms,看起来并不算特别高,但测试过程中存在约 0.5%~1% 的波动性丢包。
很多人看到 1% 丢包,会认为影响不大。对网页打开来说,它可能只是偶尔慢一下;对长时间运行的单 TCP 下载来说,影响却可能非常明显。
TCP 将丢包视为网络拥塞信号。一旦发现数据包没有正常确认,就可能降低拥塞窗口,减少发送速度。窗口刚刚恢复,又出现一次丢包,发送速率便再次下降。
于是监控中会出现一种典型现象:
速度从 1MB/s 上升到 2MB/s
随后突然下降
再次缓慢恢复
然后又下降
服务器出口一直没有跑满,并不是服务器不愿意发送,而是这个 TCP 连接不断因为丢包收缩发送窗口。
多线程下载之所以明显更快,是因为每个连接分别维护自己的拥塞窗口。一个连接因丢包降速时,其他连接仍然可以继续传输,多个连接叠加后,更容易利用剩余带宽。
这也解释了为什么测速网站显示接近 100Mbps,浏览器下载某个文件却只有 1MB/s。测速工具通常会创建多个并发连接,而普通文件下载很多时候只有一个主要连接,两者测试的并不是完全相同的网络能力。
用 iperf3 把服务器问题和线路问题分开
为了确认问题不在 Nginx,我们又进行了一组 iperf3 测试。
服务端运行:
iperf3 -s
客户端先测试单连接:
iperf3 -c 服务器IP -t 30
单连接结果约为:
9Mbps~18Mbps
随后测试 8 个并发连接:
iperf3 -c 服务器IP -P 8 -t 30
总带宽达到:
82Mbps~94Mbps
这组结果与文件下载测试基本一致,说明问题发生在端到端的单 TCP 传输过程中,而不是 Nginx 的文件发送逻辑。
如果 iperf3 单连接和多连接都很低,就要继续检查服务器总带宽、机房端口、路由拥塞、客户端接入带宽和运营商限制。
如果 iperf3 速度正常,只有 HTTP 下载慢,则应回到 Web 服务层,检查反向代理、限速模块、PHP 输出、对象存储回源或者应用程序读取文件的方式。
测试时还应注意,客户端和服务端的角色最好互换一次:
iperf3 -c 服务器IP -R -t 30
-R 表示反向测试。部分线路上下行质量并不对称,只测试一个方向,可能会漏掉回程拥塞或策略路由问题。
看见 Retr 和重传,比只看 Ping 更有价值
单纯 Ping 服务器,只能看到少量 ICMP 数据包的延迟和丢包,不能完整反映大流量 TCP 传输情况。
在 Linux 服务器上,可以在下载过程中查看连接状态:
ss -ti
重点观察以下信息:
cwnd
rtt
retrans
pacing_rate
delivery_rate
其中,cwnd 是当前拥塞窗口,rtt 是连接往返延迟,retrans 与重传有关。
如果下载速度低时,拥塞窗口很小,同时重传持续增加,问题通常更偏向线路丢包、拥塞或者 TCP 调整过程。
还可以配合 MTR 连续测试:
mtr -rwzc 200 客户端IP
但不能只看到某一跳丢包,就认定那一跳存在故障。有些路由器会降低 ICMP 响应优先级,中间节点显示丢包,最终目标却没有丢包,这种情况不一定影响实际传输。
真正值得关注的是最终节点是否丢包、延迟是否持续抖动,以及 TCP 测试中是否出现大量重传。
线路不是唯一变量,客户端也可能制造瓶颈
案例继续排查时,我们换了一台同运营商、同城市的客户端测试,单连接速度提高到约 4MB/s。原客户端改用网线连接后,速度也从 1.1MB/s 提升到了 3MB/s 左右。
这说明原来的 Wi-Fi 环境同样参与了限速。
无线干扰、路由器性能、客户端杀毒软件、浏览器扩展、家庭宽带晚高峰拥塞,都可能让服务器端看起来“有带宽却发不出去”。
因此,排查单连接下载速度时,不能只围着香港服务器修改参数。至少要更换一次客户端网络,例如:
从 Wi-Fi 改为有线连接
从家庭宽带改为手机热点
更换不同运营商测试
使用另一台电脑下载
避开晚高峰再次测试
如果只有某个地区或某个运营商速度低,而其他地区正常,问题更可能出在线路方向,而不是服务器本身。
也有一些低速,确实发生在服务器内部
并不是所有“多线程快、单线程慢”的问题都来自网络。
假设服务器提供的并不是本地 NVMe 静态文件,而是由应用程序动态读取、压缩或者从远程存储回源,单个请求可能受到应用层限制。
例如 Nginx 配置中出现:
limit_rate 1024k;
这会把单个请求限制为每秒 1024KB。用户开启 8 个连接后,总速度可能达到约 8MB/s,看起来与 TCP 单连接问题非常相似。
反向代理中还可能存在:
proxy_limit_rate
X-Accel-Limit-Rate
部分下载程序、网盘系统或业务代码也会按用户、文件或连接限制速度。
因此,在确认多线程明显快于单线程后,不能直接断定线路有问题。还要使用 iperf3 绕过 HTTP 服务测试,并检查 Nginx 配置:
nginx -T | grep -E "limit_rate|proxy_limit_rate"
同时观察磁盘和系统负载:
iostat -x 1
sar -n DEV 1
top
如果磁盘 %util 长时间接近 100%,读取延迟持续升高,或者下载文件实际位于性能较差的机械硬盘、网络磁盘上,服务器也可能无法稳定输出数据。
不过对于正常的 NVMe SSD 而言,读取一个大文件所需的几十到几百 MB/s 并不困难,100Mbps 下载只需要约 12.5MB/s,通常不会首先碰到磁盘瓶颈。
不要一看到速度低,就盲目修改 TCP 参数
网上常见的做法,是直接复制一组 sysctl 网络优化参数,提高 tcp_rmem、tcp_wmem,或者启用某种拥塞控制算法。
这些调整有时有效,但不能代替诊断。
可以先查看当前拥塞控制算法:
sysctl net.ipv4.tcp_congestion_control
查看系统支持的算法:
sysctl net.ipv4.tcp_available_congestion_control
在高延迟、存在轻微随机丢包的线路中,BBR 有时比传统基于丢包判断拥塞的算法表现更好。但它不能修复严重丢包、错误路由、运营商拥塞,也不能突破应用层限速。
如果服务器原本运行正常,修改内核参数后反而出现高并发连接异常、内存占用增加或连接不稳定,排障难度会更高。
更稳妥的顺序是:先用单连接和多连接测试确认差异,再用 iperf3 绕过应用层,随后查看重传、延迟和路由质量,最后才判断是否需要调整系统参数或更换线路。
同一台香港服务器,为什么不同用户感受完全不同?
香港服务器的网络表现不仅取决于“香港”这个地理位置,还取决于服务器去程和回程经过的运营商线路。
同样是 100Mbps 带宽,普通国际 BGP、三网优化线路、CN2、CMIN2、联通优化线路,在中国大陆不同运营商中的单连接表现可能差异很大。
一名广东电信用户下载速度慢,并不能直接证明服务器对所有用户都慢。可能出现以下情况:
广东电信:1.5MB/s
北京联通:7MB/s
上海移动:9MB/s
海外用户:10MB/s
这种结果说明服务器整体输出能力正常,但面向广东电信的路径质量不理想。
如果业务主要服务中国大陆用户,选购香港服务器时不应只看“100M 带宽”或“1G 端口”,还需要关注线路类型、目标地区、运营商覆盖和晚高峰表现。
端口大,代表服务器具备更高的总吞吐能力;线路稳定,才更有利于单连接持续提速。两者不能互相替代。
遇到这类问题,可以按一次下载过程重新观察
当香港服务器再次出现“带宽没有跑满,但下载速度很低”时,先不要急着判断带宽不足。
先记录单连接速度,再增加到 4~8 个连接。如果多连接能够接近服务器带宽上限,说明服务器具备总吞吐能力,应重点检查单连接 TCP 表现和应用层限速。
随后用 iperf3 测试单流、多流和反向传输,确认问题是否脱离 HTTP 服务仍然存在。测试过程中同步观察 ss -ti 中的延迟、拥塞窗口和重传,再结合不同地区、不同运营商客户端交叉验证。
如果问题集中在一个运营商方向,继续修改服务器 CPU、内存或硬盘通常不会带来明显改善。更换合适的香港优化线路,往往比盲目升级硬件更有效。
而在正式下载业务上线前,最好同时保存单连接、多连接和晚高峰测试结果。只看一次测速网站跑出的带宽数字,很容易掩盖真实用户下载时遇到的延迟、丢包和单流性能问题。