上一篇 下一篇 分享链接 返回 返回顶部

如何在香港服务器的Ubuntu系统上启用BBR v2拥塞控制,优化跨境长距离TCP传输性能?

发布人:Minchunlin 发布时间:2025-08-29 10:26 阅读量:1068


那天是香港葵涌机房的夜班。我把工单夹在臂弯,蹲在机柜底部把一根短跳线从 X710 的 eth0 换到上联口,前面屏幕上 Nginx access.log 像打点计时一样刷个不停。跨境下载却上不去:mtr -rwzc 200 量出来 RTT 150–190ms,偶发 0.2–0.6% 丢包;ss -ti 能看到 CUBIC 的 cwnd 一路拉锯,时不时被丢包打回去。大文件分发实测 iperf3 -P 4 -t 60 也稳定不下来。我当场决定把这台 Ubuntu 的拥塞控制从 CUBIC 直接切到 BBR 家族,目标很简单:把这条长肥管道(LFN)里的带宽、时延积吃满,别让“跨境+小丢包”继续卡着我们的吞吐。

先把路说清楚,别绕弯。主线 Linux 只有 BBR v1,开箱即用;要上 BBR v2,只有两条实操路子:

  • A 路:换到自带 bbr2 的内核(比如某些版本的第三方内核发行包,老版本提供 bbr2,新版本很多直接把 BBR v3 做成默认实现)。
  • B 路:在测试机上自己编入 BBR v2 的补丁,整套内核一起编装,再拿到生产验证。

我的做法是先在这台香港节点把 HWE/新内核跑起来,确认驱动没坑,然后优先走 A 路快速落地;如果业务曲线还想再抬一点,再在旁路测试机走 B 路深入对比。总之,别幻想一句 sysctl net.ipv4.tcp_congestion_control=bbr2 就能生效——内核里没有 bbr2,命令只会报错;先把内核准备好,后面调 fq、ECN 才有意义。

我这台“问题机器”的原始画像

维度 参数
机房/网络 香港本地二线 ISP 上联,BGP 到国内运营商,跨境链路偶发小丢包
服务器 1U、AMD EPYC 7302P(16C)、128GB ECC
存储 Samsung PM9A3 3.84TB NVMe ×2(RAID1)
网卡 Intel X710-DA2 10GbE(ixgbe 驱动)
OS Ubuntu Server 22.04.5 LTS (Jammy),起初是 5.15 GA 内核,后换 6.8 HWE(理由见下)
服务 Nginx + rsync/ssh/scp,主要是大文件分发
典型路径 香港 ↔ 华南/华东:RTT 35–55ms;香港 ↔ 北美西海岸:RTT 150–190ms(本文着重这条)

注:Jammy 的 HWE 线现在用到 6.8,对网卡/驱动/栈的细节更新不少,升级 HWE 很稳。命令:sudo apt install linux-generic-hwe-22.04。

为什么不是直接上 BBRv1?BBRv2(顺带 v3)到底好在哪

BBR v1 已在 Linux 主线多年可用,打开即用(bbr),但在高丢包并发或与传统 CUBIC/Reno 共存时的公平性、丢包敏感度上有争议。

BBR v2 针对 v1 的痛点做了很多收敛与公平性的改良,并引入对 ECN 的支持;在高 RTT/低比例丢包的长链路环境,v2 往往更平滑。

现状是:主线内核仍是 v1;要用 v2,需要 自编补丁或装第三方内核(比如过去的 XanMod “bbr2” 分支版本)。近一两年部分第三方内核甚至把 BBRv3 做成默认(如果你看到 “bbr3”,那是更新的实验线)。

实操路线图(先上结论)

  • 先快速启用 BBR v1 + fq,立竿见影、风险极低。
  • 确认业务提升后,再评估是否要上 BBR v2(两种方式:A. 安装带 bbr2 的内核;B. 自编 google/bbr v2alpha 补丁内核)。
  • v2 生效后,开启 ECN、调好 fq 和少量 sysctl,最后对照测试。
  • 如果你装的是较新的第三方内核,看到的是 bbr3,那是“更进一步”的实验分支,不影响本文流程(只是把 bbr2 改成 bbr3)。

基线测试(CUBIC 下的真实测得)

# 服务器(HK)测到海外落地点(例如美西):
iperf3 -c <US-West-IP> -P 4 -t 60 -R
mtr -rwzc 200 <US-West-IP>

# 客户端(国内)回打到HK:
iperf3 -c <HK-IP> -P 4 -t 60

我们那晚的样本(节选):

场景 RTT 丢包 算法 并发(-P) 吞吐(Gbps) 重传
HK→US(CUBIC) 170ms 0.3% cubic 4 0.82 1.8%
US→HK(CUBIC) 170ms 0.3% cubic 4 0.74 2.1%

1. 快速启用 BBR v1(所有 Ubuntu 适用)

BBR 推荐配合 fq 队列用于 pacing,避免退回到栈内“粗糙”节流。

# 1) 确认当前拥塞算法
sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control
uname -r

# 2) 开启 fq + bbr
sudo tee -a /etc/sysctl.conf >/dev/null <<'EOF'
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
EOF
sudo sysctl -p

# 3) 验证
sysctl net.ipv4.tcp_congestion_control   # 期望输出 bbr
tc qdisc show dev eth0                   # 期望看到 fq
lsmod | grep bbr                         # 期望看到 tcp_bbr

如果你还在 22.04 GA 5.15,强烈建议顺手升级到 6.8 HWE(对网卡队列和拥塞控制细节更友好):

sudo apt install linux-generic-hwe-22.04。

BBR v1 上线后的对照样本:

场景 RTT 丢包 算法 并发(-P) 吞吐(Gbps) 重传
HK→US(BBR v1) 170ms 0.3% bbr 4 1.35 0.6%
US→HK(BBR v1) 170ms 0.3% bbr 4 1.28 0.7%

到这里,多数人已经“够用了”。如果你还想在高 RTT/小丢包场景进一步压榨吞吐并改善并发公平性,继续看 v2。

2. 启用 BBR v2:两条路

先说硬话:bbr2 不在 Ubuntu 主线,你不能直接 net.ipv4.tcp_congestion_control=bbr2 就指望成功;报错“Couldn't write 'bbr2'...” 是正常的——那说明你的内核没有 bbr2。

2A) 装一个“带 bbr2 的内核”(实战更省心)

XanMod 曾在 6.2 系列引入了 “BBRv2(bbr2)” 的实现(可以用旧版本包),其安装极其方便(APT 仓库一键安装)。最新的 XanMod 主页已显示 BBRv3 内建为默认(如你想体验 v3 也只需把算法名换成 bbr/bbr3 对应内核实现),但要特定使用 v2,请选择包含 “bbr2” 的版本(例如 6.2.x 系列)。

安装步骤(以 Ubuntu 22.04/24.04 为例)

(注意:新内核可能触发 DKMS 模块重编译,ZFS/专有驱动要确认兼容)

# 加仓库与密钥(官网指引)
wget -qO - https://dl.xanmod.org/archive.key | \
  sudo gpg --dearmor -o /etc/apt/keyrings/xanmod-archive-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/xanmod-archive-keyring.gpg] \
http://deb.xanmod.org $(lsb_release -sc) main" | \
  sudo tee /etc/apt/sources.list.d/xanmod-release.list

sudo apt update
# 安装你需要的具体版本(举例:x64v3 主线;若需旧版 bbr2,请改装 6.2.x 对应包)
sudo apt install linux-xanmod-x64v3
# 若需旧版手动下载 .deb 安装,可到 XanMod 下载页挑相应版本
# 安装后重启
sudo reboot

切换到 bbr2 并验证:

# 只有在内核确实包含 bbr2 时,下面才会成功
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr2
sysctl net.ipv4.tcp_available_congestion_control  # 应看到 bbr2
lsmod | grep bbr                                  # 看到 tcp_bbr 或 tcp_bbr2

备注:XanMod 官网现在强调的是 BBRv3(built-in: tcp_bbr),如果你安装的是新内核,算法名仍是 bbr(实现为 v3);要“指定用 v2”,就装**历史版本(6.2.x)**或其他仍包含 bbr2 的构建。

2B) 自编 google/bbr v2alpha 补丁内核(高阶玩家)

Google 的 BBRv2 v2alpha 分支长期以 补丁集形式提供,并依赖内核 TCP 栈的其他改动,不能像普通模块一样“脱树”编译后随便插到发行版内核中用(很多人卡在这一步)。官方曾将 v2alpha 从 5.4 rebase 到 5.10。思路是拉下该分支,按脚本编译安装整套内核。

粗略流程(示意):

# 1) 准备依赖
sudo apt update
sudo apt install build-essential bc bison flex libssl-dev libelf-dev dwarves

# 2) 获取 google/bbr 仓库(v2alpha)
git clone https://github.com/google/bbr.git
cd bbr
# 分支示例:v2alpha(实际以仓库说明为准)
git checkout v2alpha

# 3) 使用仓库附带脚本/说明构建(不同时间点细节略有变化)
# 重点:该分支包括对 TCP 栈的配套改动,需整体编译,不可 out-of-tree
# 完成后安装新内核并重启

启用与验证:

sudo sysctl -w net.ipv4.tcp_congestion_control=bbr2
[ -d /sys/module/tcp_bbr2/parameters ] && ls /sys/module/tcp_bbr2/parameters

友情提示:Secure Boot 开着会阻止未签名内核/模块加载,必要时在 BIOS 里关掉或使用 MOK(Machine Owner Key)签名流程。

3. v2 上线后的“周边微调”

(1) fq 队列 & pacing

sudo sysctl -w net.core.default_qdisc=fq
sudo tc qdisc replace dev eth0 root fq   # 让当前网卡立刻用 fq

BBR 与 fq 配合可获得更稳定的 pacing;否则内核会用栈内 fallback 节流,效果逊色。

(2) 开启 ECN(v2 兼容更好)

sudo sysctl -w net.ipv4.tcp_ecn=1

(若路径中有中间盒/旧设备对 ECN 不友好,再关掉。)

(3) 合理的缓冲与窗口

sudo tee /etc/sysctl.d/99-tcp-tune.conf >/dev/null <<'EOF'
# BDP 充足的收发缓存
net.core.rmem_max=67108864
net.core.wmem_max=67108864
net.ipv4.tcp_rmem=4096 87380 33554432
net.ipv4.tcp_wmem=4096 65536 33554432

# 常用安全开关
net.ipv4.tcp_mtu_probing=1
net.ipv4.tcp_slow_start_after_idle=0
EOF
sudo sysctl --system

4. BBR v2 的对照测试(实测样本)

场景 RTT 丢包 算法 并发(-P) 吞吐(Gbps) 重传
HK→US(BBR v2) 170ms 0.3% bbr2 4 1.58 0.4%
US→HK(BBR v2) 170ms 0.3% bbr2 4 1.52 0.5%

在我们这条跨境长链路上,v2 相比 v1 又抬了 15–20% 左右,抖动更小、重传更低。学术界和业界的评测也普遍指出:RTT 越高、丢包率越高,BBR(尤其 v2)相对 CUBIC 的优势越明显;而 v2 的设计更关注公平性与 ECN。

5. 线上“坑点”与我的处理

Couldn't write 'bbr2' ...:你的内核没有 bbr2。
解法:走 2A 或 2B,安装/编内核后再 sysctl。

fq 没生效,估计还在 pfifo_fast:tc qdisc show dev eth0 能看出来。
解法:tc qdisc replace dev eth0 root fq;并在 /etc/sysctl.conf 设置默认 qdisc。

DKMS 模块/专有驱动不兼容新的内核(ZFS/NVIDIA/虚拟化驱动)。
解法:预装 dkms 依赖,评估版本,必要时锁定到某个已验证的内核版本(XanMod 历史包/Ubuntu HWE)。

Secure Boot 拒绝加载:自编/第三方内核或模块未签名。
解法:临时关闭 Secure Boot 或走 MOK 签名流程。

容器里改不动 sysctl/qdisc:容器隔离导致。
解法:在 宿主机 配置;或者容器以 --sysctl/特权方式运行(建议仍以宿主机为主)。

PMTUD 黑洞导致偶发断流(跨境偶有)。
解法:mangle 表钳制 MSS:

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

6. 回滚与分流的小技巧

一键回滚到 CUBIC:

sudo sysctl -w net.ipv4.tcp_congestion_control=cubic

按进程/端口临时指定算法(用于 A/B):

应用可用 setsockopt(TCP_CONGESTION) 选 cubic/bbr/bbr2;或为测试程序临时写个 wrapper。

只给跨境业务走 BBR:在多业务机器上,我会把国内面向的端口保守用 CUBIC,跨境分发的端口用 BBR/BBR2,避免极端路径互相影响。

7. 现场速查清单(我贴在机柜门内侧的那张)

# 看拥塞算法与内核版本
sysctl net.ipv4.tcp_congestion_control
sysctl net.ipv4.tcp_available_congestion_control
uname -r

# fq 是否在跑
tc qdisc show dev eth0

# 传输时看套接字状态(拥塞算法、拥塞窗口等)
ss -ti '( dport = :443 )' | head -n 20

# 网络统计(重传、拥塞等)
nstat -az | egrep 'Tcp(Timeouts|RetransSegs|FastRetrans|Loss)'

8. 参考与延伸(精选,非百科式)

  • Ubuntu HWE 内核线与生命周期(为何我从 5.15 提到 6.8):HWE 提供较新的驱动/内核。
  • BBR 快速启用(v1,含 fq 建议):在 Ubuntu 上改 sysctl 即可。
  • fq 与 BBR 的 pacing 配合:推荐和原因。
  • 主线现状:Linux 仍提供 BBRv1,Google 团队近年把精力放在 BBRv3 的 upstream 工作上(所以你看到一些第三方内核说“内建 BBRv3”)。
  • XanMod:APT 安装指引(新版默认 BBRv3);历史版本里可找到“bbr2”。
  • BBRv2 的公平性/ECN 背景与评测(Dropbox/ESnet 等)。

那晚两点半,我把 bbr2 + fq + ecn 一套推进生产,最后一轮 iperf3 的曲线像是被打磨过,抖动低得让人安心。早上九点客服同事在群里扔来一句话:“昨晚北美回源稳定了”。我笑着把机柜门合上,心里明白——BBR v2 不是什么“银弹”,但在跨境长距离、轻微丢包的链路上,它把属于网络模型的那一点从容带了回来。

如果你也在香港(或其他边缘节点)背着跨境流量的锅,先用 v1 验身,再上 v2 精修;若你装的是带 BBRv3 的内核,也不妨顺势尝鲜。网络世界一直在进化,我们就站在机柜前,做那个把“变化”落地成“稳定”的人。

目录结构
全文