帮助中心

服务器、网络和账户的分步教程。

网络与 IP

Linux 长距离网络调优:TCP 缓冲区、BBR + fq、MTU/MSS 与 sysctl 设置

Linux 长距离网络调优:TCP 缓冲区、BBR + fq、MTU/MSS 与 sysctl 设置

在长距离、高延迟的线路上(例如东京、首尔或莫斯科的 VPS 服务欧洲或中国大陆用户),单条 TCP 连接的速度往往卡在内核的套接字缓冲区和拥塞控制算法上,而不是 500 Mbps 的端口。本文介绍如何算出这个上限,应用一套安全的 sysctl 配置(更大的 TCP 缓冲区、BBR + fq),排查隧道上的 MTU/MSS 问题,用 iperf3 做前后对比,以及如何完整回滚。

如果你只想开启 BBR,看简短的BBR 开启教程就够了。本文在此基础上进一步讲解缓冲区和 MTU。命令适用于 Debian 12/13、Ubuntu 22.04/24.04 以及 Rocky Linux/AlmaLinux 9,这些系统的内核都自带 BBR。

为什么距离会限制单连接速度

TCP 同一时间只能有一定量“已发出但未确认”的数据在路上,这个量就是带宽时延积(BDP):带宽 × 往返时间(RTT)。如果缓冲区允许的窗口小于 BDP,连接就得停下来等确认,端口再快也跑不满。

计算示例:500 Mbps 端口,RTT 为 180 ms。

  • BDP = 500,000,000 bit/s × 0.18 s = 90,000,000 bit,约 11.25 MB。
  • Linux 常见的默认最大接收缓冲区(tcp_rmem)为 6 MB,其中一部分还要留作开销。6 MB ÷ 0.18 s 理论上最多约 280 Mbps,实际单连接往往只有 150–200 Mbps。
  • 把上限调到 32 MB 后,180 ms 下的理论上限超过 1 Gbps,在 500 Mbps 端口上缓冲区就不再是瓶颈。

丢包会让情况更糟:传统的 CUBIC 算法每遇到一次丢包就大幅降速,在长距离线路上要很久才能恢复。BBR 则根据估算的带宽和 RTT 来发送,对国际线路上偶发的丢包耐受度高得多。RTT 取决于用户所在位置,请用 ping 实测。

关于线路本身:JUSTG 莫斯科机房使用中国电信 CN2 GIA,到中国大陆的路径更干净;东京和首尔使用亚洲优化线路。好的线路能减少丢包和抖动,但 RTT 由物理距离决定,所以无论哪个机房,调优缓冲区都有帮助。

第 1 步:查看当前设置

uname -r
sysctl net.ipv4.tcp_congestion_control net.ipv4.tcp_available_congestion_control
sysctl net.core.default_qdisc net.core.rmem_max net.core.wmem_max
sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem net.ipv4.tcp_mtu_probing
ip -br link
tc qdisc show

记下内核版本、当前拥塞控制算法(通常是 cubic)、默认队列(通常是 fq_codel)、缓冲区数值以及网卡名称(eth0、ens3 等,下文的 eth0 请替换成你的网卡名)。

第 2 步:备份并检查冲突的配置文件

sudo sysctl -a 2>/dev/null | grep -E 'tcp_(rmem|wmem|congestion_control|mtu_probing|notsent_lowat)|core\.(rmem_max|wmem_max|default_qdisc|somaxconn)' | sudo tee /root/sysctl-before.txt
grep -rnE 'congestion|qdisc|rmem|wmem' /etc/sysctl.conf /etc/sysctl.d/ 2>/dev/null

第一条命令把当前数值保存到 /root/sysctl-before.txt,方便以后恢复;第二条列出已经设置了相同参数的其他文件。/etc/sysctl.d/ 下的文件按文件名顺序加载,/etc/sysctl.conf(如果存在)最后加载,那里的旧配置可能会悄悄覆盖你的新文件。请删除或注释掉重复项。

Debian 13 默认不再读取 /etc/sysctl.conf,这也是建议把配置放在 /etc/sysctl.d/ 下的原因之一。

第 3 步:创建调优配置

sudo tee /etc/sysctl.d/99-network-tuning.conf > /dev/null <<'EOF'
# Queueing discipline and congestion control
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# Socket buffer ceilings (32 MB) for high-RTT paths
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
net.ipv4.tcp_rmem = 4096 131072 33554432
net.ipv4.tcp_wmem = 4096 16384 33554432

# Recover from PMTU black holes
net.ipv4.tcp_mtu_probing = 1

# Keep unsent data in the send buffer small (lower latency)
net.ipv4.tcp_notsent_lowat = 131072

# Larger accept queue for busy services
net.core.somaxconn = 4096
EOF
echo tcp_bbr | sudo tee /etc/modules-load.d/bbr.conf

各部分的作用:

  • default_qdisc = fq 和 bbr:拥塞控制使用 BBR,队列使用 fq 做平滑的发包节奏控制。从内核 4.13 起 BBR 不依赖 fq 也能工作,但两者搭配仍是推荐做法。
  • rmem_max/wmem_max 与 tcp_rmem/tcp_wmem:三个数字分别是每个套接字的最小值、默认值和最大值(字节)。Linux 自动调优只在连接需要时才扩大缓冲区,32 MB 上限不代表每条连接都占用 32 MB。mini 套餐(512 MB 内存)可以改用 16777216(16 MB),在 RTT 约 150 ms 以内仍能跑满 500 Mbps。
  • tcp_mtu_probing = 1:内核检测到路径 MTU “黑洞”(大包被悄悄丢弃)时,会为该连接降低包大小,而不是一直卡住。
  • tcp_notsent_lowat:限制套接字里排队等待发送的数据量,在不影响吞吐的前提下降低交互流量和 HTTP/2 的延迟。
  • somaxconn = 4096:连接接受队列上限。内核 5.4 及以上默认已经是 4096,这一行只对老系统有影响,同时也表明配置意图。

最后一行确保开机时先加载 tcp_bbr 模块,再应用 sysctl 参数。

第 4 步:应用并验证

sudo modprobe tcp_bbr
sudo sysctl --system
sysctl net.ipv4.tcp_congestion_control net.core.default_qdisc net.ipv4.tcp_rmem net.ipv4.tcp_wmem

输出中应能看到 bbr、fq 和新的缓冲区数值。修改 default_qdisc 只影响之后新建的队列,现有网卡在重启前仍使用旧队列。如需立即切换:

sudo tc qdisc replace dev eth0 root fq
tc -s qdisc show dev eth0

然后新建一条连接(例如重新打开 SSH 或开始一次下载),用 ss 查看,IP 填对端地址:

ss -tin dst 203.0.113.20

输出会显示每条连接的 bbr、实测 rtt 和当前拥塞窗口。修改之前建立的连接要重新连接后才会使用新设置。

第 5 步:排查并解决 MTU/MSS 问题

MTU 问题的表现和缓冲区太小完全不同,典型症状有:

  • ping 和小请求正常,但大文件下载或上传传了几 KB 就卡住;
  • SSH 能登录,但命令输出一多就卡死;
  • 部分 HTTPS 网站只加载一半或打不开,多见于 VPN、WireGuard、GRE 或 PPPoE 链路。

原因通常是链路上某一段 MTU 小于 1500,而 ICMP “需要分片”消息又被拦截了。用“禁止分片”参数测试:1472 字节数据加 28 字节包头正好是 1500 字节:

ping -c 3 -M do -s 1472 203.0.113.20
ping -c 3 -M do -s 1400 203.0.113.20
tracepath -n 203.0.113.20
ip link show dev eth0

如果 1472 不通而 1400 能通,就逐步调小直到能通,能通的最大值加 28 就是路径 MTU。tracepath 也会显示沿途的 pmtu。不要在防火墙里屏蔽全部 ICMP,路径 MTU 发现依赖它。

如果服务器为其他设备转发流量(WireGuard 或其他 VPN 服务端、GRE 隧道、NAT 网关),请对转发的连接做 TCP MSS 钳制,让两端协商出适合隧道的分段大小。使用 nftables(Debian 12/13 和 Rocky/Alma 9 的默认方案):

sudo tee /etc/nftables-mssfix.nft > /dev/null <<'EOF'
table inet mssfix
delete table inet mssfix
table inet mssfix {
    chain forward {
        type filter hook forward priority mangle; policy accept;
        tcp flags & (syn | rst) == syn tcp option maxseg size set rt mtu
    }
}
EOF
sudo nft -f /etc/nftables-mssfix.nft
sudo nft list table inet mssfix

这条规则会把 SYN 包里的 MSS 改成与出口路由 MTU 相符的值。Debian/Ubuntu 上要在重启后保留,请在 /etc/nftables.conf 末尾加入 include "/etc/nftables-mssfix.nft",并执行 sudo systemctl enable nftables。Rocky/Alma 如果使用 firewalld,不要另外启用 nftables 服务,请改用下面 WireGuard 的 PostUp 方法。同样的规则用 iptables 写法如下(如未安装请先安装 iptables 软件包):

sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

WireGuard 最简单的持久化方式是写进 wg-quick 配置(例如 /etc/wireguard/wg0.conf),规则会随隧道启动和关闭自动添加、删除:

[Interface]
MTU = 1420
PostUp = iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostDown = iptables -t mangle -D FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

1420 是 WireGuard 的默认 MTU,在普通 1500 字节的路径上是安全值。IPv4 下 TCP 的 MSS = MTU − 40,所以 1420 对应的 MSS 是 1380。如果服务器只收发自身流量、不为别人转发,一般不需要钳制:内核会根据网卡 MTU 选择 MSS,剩下的交给 tcp_mtu_probing。

第 6 步:用 iperf3 做前后对比

在修改前后各跑一次相同的测试,尽量选在一天中相近的时段。两端都需要安装 iperf3(apt install iperf3 或 dnf install iperf3):

# On the VPS (allow TCP 5201 in the firewall only for the test)
iperf3 -s

# On your own computer
iperf3 -c 203.0.113.10 -t 20            # upload: you -> VPS
iperf3 -c 203.0.113.10 -t 20 -R         # download: VPS -> you
iperf3 -c 203.0.113.10 -t 20 -R -P 4    # download, 4 parallel streams

如何解读结果:

  • -R 是网站访客和下载用户实际体验到的方向,因为此时 VPS 是发送方,VPS 上的拥塞控制和发送缓冲区影响最大。
  • -P 4 会同时开 4 条连接。如果 4 条加起来比 1 条快很多,说明单连接受窗口大小或丢包限制,这正是缓冲区和 BBR 要解决的问题。如果两者都一样慢,就要看线路、客户端本地网络或客户端的接收缓冲区。
  • 在 -R 模式下你的电脑是接收方,它的接收缓冲区同样有影响。新版 Windows、macOS 和 Linux 都会自动调整,但你这边的老旧路由器或 VPN 仍可能成为瓶颈。
测试时间请控制在 20–30 秒,结束后按 Ctrl+C 停止 iperf3 -s,并重新关闭 5201 端口。长时间满速测试会消耗流量,长期占用共享端口 70% 以上也违反合理使用规则。

第 7 步:如需回滚

最干净的回滚方式是删除这两个文件并重启:

sudo rm /etc/sysctl.d/99-network-tuning.conf /etc/modules-load.d/bbr.conf
sudo reboot

只删除文件再执行 sysctl --system 不会恢复原值,这些参数会一直生效到重启为止。如果不想重启,请按备份文件里的数值手动设置。当前 Debian/Ubuntu 内核的常见默认值如下:

cat /root/sysctl-before.txt
sudo sysctl -w net.ipv4.tcp_congestion_control=cubic net.core.default_qdisc=fq_codel
sudo sysctl -w net.ipv4.tcp_rmem="4096 131072 6291456" net.ipv4.tcp_wmem="4096 16384 4194304"
sudo sysctl -w net.core.rmem_max=212992 net.core.wmem_max=212992

如果还添加了 MSS 规则,用 sudo nft delete table inet mssfix 删除(iptables 则把命令中的 -A 换成 -D),并从配置中去掉 include 行或 PostUp/PostDown 行。

FAQ

这些设置能降低 ping 值吗?

不能。RTT 由距离和路由决定。缓冲区和 BBR 让单条连接在这个 RTT 下用上更多带宽,fq 加 tcp_notsent_lowat 能在高负载时减少排队延迟,但基础延迟不会变。

1 GB 套餐用 32 MB 缓冲区安全吗?

正常业务下是安全的。这些数值是每个套接字的上限,自动调优只在连接确实需要时才扩大缓冲区,内核的全局 tcp_mem 上限也会根据内存大小自动设定。512 MB 的 mini 套餐建议用 16 MB。

调优后速度还是慢,应该给客服提供什么?

请在 Technical support 部门提交工单,附上服务器 IP、带时区的时间、带与不带 -R、-P 4 的 iperf3 结果,以及双向的 mtr 结果。收集方法见测速教程。JUSTG 提供 7×24 小时 AI 客服(工单),需要人工处理的问题会由工程师跟进。

这篇文章有帮助吗?
帮助中心
网络与 IP VPS 网速测试:用 iperf3、Speedtest CLI 与 curl 测试服务器带宽与延迟 完整的 VPS 网速测试要回答两个问题:服务器能收发多少带宽,以及数据包在服务器与用户之间传输要多久。本文说明如何在运行 Debian/Ubuntu 或 CentOS/Rocky/AlmaLinux 的 JUSTG 云服务器或独立服务器上,使用 iperf3… 网络与 IP Linux 添加 IP 地址教程:在 Ubuntu、Debian、CentOS 与 Rocky Linux 绑定额外 IPv4 若您的 JUSTG 云服务器已添加额外 IP,或您为 JUSTG 独立服务器申请了 /24 IP 段,必须先在 Linux 添加 IP 地址,该 IP 才能响应流量。本文说明如何用 ip addr add 临时绑定额外 IPv4、如何在 Ubuntu 用… 网络与 IP Linux VPS 开启 TCP BBR 拥塞控制教程(Debian、Ubuntu、CentOS、Rocky Linux) TCP BBR 是 Google 开发的拥塞控制算法,自 Linux 内核 4.9 起内置。在高延迟的长距离线路上,例如从 JUSTG 约翰内斯堡或莫斯科机房的服务器发送数据到亚洲用户,默认的 CUBIC 算法只要遇到少量丢包就会大幅降速;BBR… 网络与 IP 什么是原生 IP?如何查询服务器 IP 的归属地 原生 IP 是指注册在服务器实际所在国家网络名下的 IP 地址,因此 whois 记录和 IP 地理位置数据库显示的都是这个国家。用 whois 加一次地理位置查询,一分钟就能查清任意服务器 IP 的归属地,方法见下文。JUSTG 东京和首尔云服务器均配备日本、韩国原生… 网络与 IP 如何检测 VPS 能否解锁 Netflix、Disney+ 和 AI 服务 流媒体和 AI 服务根据服务器的公网 IP 判断你所在的位置,因此检测 VPS 是否“解锁”,先确认 IP 所属国家,再直接在服务器上逐项测试。本文介绍 Windows Server(通过 RDP 在浏览器中测试)和 Linux(用 curl 测试)两种方法,并附上 JUSTG…
AlipayUnionPayVISAMastercardPayPalUSDTstripe