幫助中心

伺服器、網路和帳戶的分步教程。

網路與 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