VPS TCP 调优实录:tcpfit/BBR 实测数据
上个月排查一台芝加哥 VPS 时遇到个典型问题:千兆端口,多线程 iperf3 能跑到 998M,但单线程死卡在 217M 左右,看 YouTube 高码率视频就转圈。机器不慢、带宽够、BBR 也开着——问题出在哪?
最后查明白是 TCP 发送缓冲太小,调完单线程直接拉到 253M。这篇把整个排查过程和实测数据整理出来,你自己遇到"节点速度上不去"时可以照着判断。
更新于 2026-08-26。工具版本以 tcpfit 的 GitHub 为准。
先说结论:三种情况,三种对策
| 你的症状 | 病根 | 调 TCP 有没有用 |
|---|---|---|
| 同机房互传都慢 | 服务器缓冲区太小 | ✅ 有用,主力战场 |
| 机房内快,国内连上去慢、重传高 | 国际链路拥塞/丢包 | ❌ 没用,物理瓶颈 |
| 单线程慢但多线程能跑满 | 单流受 RTT×缓冲限制 | ✅ 有用,就是本文主角 |
先做这个分流判断,再决定要不要动手调。很多人一上来就无脑跑一键脚本,方向错了白折腾。
一个公式:BDP 带宽时延积天花板
单条 TCP 连接的速度上限有个硬计算:
单流理论上限 = 发送缓冲区(bytes) × 8 ÷ RTT(秒)
这就是 BDP(Bandwidth-Delay Product,带宽时延积):缓冲区里最多囤这么多"在路上"的数据,RTT 越大,同样缓冲能撑的速度越低。
拿芝加哥那台算一遍:
发送缓冲 4MB,到东京 RTT 129ms
4 × 1024 × 1024 × 8 ÷ 0.129 ≈ 258 Mbps
实测 217M 卡死,和理论值 258M 对得上——不是线路不行,是缓冲装不下更多"在途数据"。这种情况下换协议、换内核都没用,把缓冲区加大就行。
反过来,RTT 小的时候这个公式基本不构成限制:
发送缓冲 11MB,同机房 RTT 8ms
11 × 8 ÷ 0.008 = 11000 Mbps ≈ 11 Gbps
缓冲根本用不满,瓶颈在别处(比如端口本身)。所以先算 BDP 再动手,一步就能判断该不该调。
第一步:定位瓶颈在哪一段
拿两台 VPS(或本机对远端)互跑 iperf3,两端都要装:
apt-get install -y iperf3 # 两端
iperf3 -s -p 39501 # 服务端
iperf3 -c <对端IP> -p 39501 -t 10 # 客户端单线程
iperf3 -c <对端IP> -p 39501 -t 8 -P 4 # 客户端 4 并发
端口用防火墙已放行的段,别为测试新开端口;测完 ss -tlnp | grep 39501 确认服务端停干净。
判读方法就一条:机房内(或近距离低 RTT)对跑快 = 服务器没问题;国内连过去慢且重传爆炸 = 国际链路的锅。
第二步:tcpfit 实际调优
服务器侧的问题交给 tcpfit 处理——2026 年 8 月发布在 NodeSeek 的开源脚本(MIT,约 1850 行 Shell),特点是按你实测的带宽和 RTT 推导参数,不是无脑套模板。
curl -fsSL https://raw.githubusercontent.com/Kylin010/tcpfit/main/tcpfit.sh -o /tmp/tcpfit.sh
chmod +x /tmp/tcpfit.sh
bash /tmp/tcpfit.sh tune --role proxy --bw 1000 --rtt 129
两个参数必须手动给准,自动探测经常不准:
--bw填真实端口带宽。KVM 虚拟网卡读不到标称速率,不知道就先跑一次 sweep 实测--rtt用ping 对端的真实值,别信默认探测
它做的事:把 net.ipv4.tcp_wmem 上限按 BDP 拉大、开 BBR + fq 队列、关 tcp_slow_start_after_idle(长连接空闲后不再重新慢启动,代理场景很重要)等 32 项。改动只落 6 个位置,都有快照可回滚:
▸tcpfit 落地的 6 个位置(出问题回滚用)
/etc/sysctl.d/99-tcpfit.conf—— sysctl 参数主体/var/lib/tcpfit/pre-tune.snapshot—— 调优前完整快照tcpfit-qdisc.service+/usr/local/sbin/tcpfit-qdisc.sh—— fq 队列管理- networkd-dispatcher 里
50-tcpfit-initcwnd—— 初始拥塞窗口 /etc/modules-load.d/tcpfit-bbr.conf—— BBR 内核模块加载
回滚:bash tcpfit.sh rollback,一条命令恢复原状。跑之前建议先 tar 一份 /etc/sysctl.d/ 双保险。
▸第三方脚本的安全审查记录
跑陌生脚本前我 grep 了一遍危险命令,有两处容易误判的点说明一下:
dd if=/dev/zero—— 用于创建 swap 文件,正常功能/dev/tcp/$host/5201—— 探测 iperf3 端口是否在线,正常功能- 写
/etc/modules-load.d/—— 加载 BBR 模块,正常功能
逐行看过上下文,没有外传数据、没有留后门动作。当然这是我的审查结论,介意的话只抄它的 sysctl 参数手改也一样。
实测数据:两台机器调优前后
案例一:芝加哥 → 东京(高 RTT,缓冲受限型)
| 项目 | 调优前 | 调优后 |
|---|---|---|
| 发送缓冲上限 | 4 MB | 32.5 MB |
| BDP 理论单流上限 | ≈258 Mbps | ≈2015 Mbps |
| iperf3 单线程实测 | 217 Mbps 卡死 | 253 Mbps |
| iperf3 4 并发 | — | 998 Mbps ≈ 千兆满速 |
RTT 129ms 下 BBR 单流 ~250M 是算法本身的物理极限,剩下的靠多连接补齐——这正是代理软件默认多连接的工作方式,所以实际体验提升非常明显。
案例二:东京 IIJ → 东京同机房(低 RTT,本来就健康)
| 项目 | 数值 |
|---|---|
| RTT | 8 ms |
| 端口 | 3 G |
| 发送缓冲上限 | 11 MB(BDP 天花板 ≈11G,远超端口) |
| iperf3 单线程 | 2.19 Gbps |
| iperf3 4 并发 | 3.04 Gbps ≈ 端口满速 |
这台调优前后几乎没差别——RTT 小的机器本来就不受缓冲限制,调了只是锦上添花。再次验证"先算 BDP"的价值:一眼就知道这台不用折腾。
泼冷水:国际链路的瓶颈,调优救不了
最关键的实测是这个。用国内的家用宽带盒子(Armbian 小主机)直连东京节点跑 iperf3:
单线程 54 Mbps / 4 并发 56 Mbps
重传 2075~22822 次 / RTT 268ms
同一台东京服务器,机房内 3 Gbps 满速,国内直连只有 54M 且重传上万——瓶颈在国际段拥塞,不在服务器。这种局面下 tcpfit、BBR、换协议全都无效,唯一的解法是绕路(中转/专线),也就是线路类型详解里讲的那套逻辑。
这也是我给机场评测定的一条铁律的由来:评测里的"速度快"必须区分是服务器快还是链路快。商家展示的服务器侧测速图再漂亮,也证明不了你连上去快。
附:真实线路测速的两个坑
写评测要拿真实数据时注意,这两个坑我都踩过:
- 别走 Tailscale 隧道测速。它的 MTU 只有 1280 且打洞失败会绕 DERP 中继,测出来的数字严重偏低。正确姿势:Tailscale 只当 SSH 管理通道,iperf3 走两端公网 IP 直连。
- 家宽对海外 UDP 经常限速。Hysteria2 这类 UDP 协议握手时通时断,先怀疑家宽 UDP QoS,别急着骂服务器。测速优先选 TCP 协议(vless-reality 等),结果稳定得多。
验证清单
调完收尾过一遍:
sysctl net.ipv4.tcp_wmem上限已提升(和调优前快照对比)sysctl net.ipv4.tcp_congestion_control返回 bbr,default_qdisc返回 fqsysctl net.ipv4.tcp_slow_start_after_idle返回 0- iperf3 服务端已停、端口已释放
- 快照文件还在
/var/lib/tcpfit/pre-tune.snapshot,随时可回滚
相关阅读
- 机场说的 IEPL、IPLC、BGP 中转都是什么? —— 线路瓶颈的结构性解释,本文"国际段救不了"的原理版
- 机场名词字典 —— BBR、倍率、Reality 这些词的速查