在長距離、高延遲的線路上(例如東京、首爾或莫斯科的 VPS 服務歐洲或中國大陸使用者),單條 TCP 連線的速度往往卡在核心的套接字緩衝區和擁塞控制演算法上,而不是 500 Mbps 的連接埠。本文介紹如何算出這個上限,應用一套安全的 sysctl 配置(更大的 TCP 緩衝區、BBR + fq),排查隧道上的 MTU/MSS 問題,用 iperf3 做前後對比,以及如何完整回滾。
為什麼距離會限制單連線速度
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(如果存在)最後載入,那裡的舊配置可能會悄悄覆蓋你的新檔案。請刪除或註釋掉重複項。
/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 仍可能成為瓶頸。
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 客服(工單),需要人工處理的問題會由工程師跟進。