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

如何在香港服务器的Ubuntu 20.04中启用TCP BBR拥塞控制算法,降低跨境访问延迟?

发布人:Minchunlin 发布时间:2025-08-22 09:44 阅读量:683


凌晨 1:40,客服把电话转给了我:“华北和华东的用户访问我们香港源站,页面经常卡住,视频也缓冲得厉害,能看看吗?”

我远程打开监控,几个指标刺眼:

  • 跨境连接 RTT(p95)在 55–80ms 摆动不算离谱,但 TTFB(p95)冲到了 600ms+。
  • TCP 重传率在晚高峰能上 2–3%。
  • 带宽并没跑满,10G 口只有 2–3G 流量,却像“堵车”。

经验告诉我:这很像 Cubic 在轻微丢包 + 中等 RTT 的跨境链路上“保守开车”了。于是我决定在这台 Ubuntu 20.04 的香港服务器上启用 TCP BBR,通过更好的拥塞控制和精准节拍(pacing)把跨境时延压下去。

环境与目标

目标:在 Ubuntu 20.04 LTS 上启用 TCP BBR(v1),降低跨境访问的 应用层延迟(TTFB、页面首屏、API 响应 p95),同时提升弱丢包场景下的 有效吞吐。

机房与硬件(实配)

项目 参数
机房 香港葵涌(双上联:CMI + HKT,BGP 汇接)
服务器 Supermicro 1U
CPU Intel Xeon Silver 4310 ×1
内存 64GB DDR4
存储 Samsung PM9A3 1.92TB NVMe
网卡 Intel X710 10GbE(上联 10G)
操作系统 Ubuntu 20.04.6 LTS(原生 5.4 内核)
业务 Nginx + Node.js,HTTP/2 为主,部分文件下载直连

备忘:Ubuntu 20.04 默认 5.4 内核已支持 BBR v1;BBR v2 未主线稳定,不追求。

基线数据(启用前)

我按惯例先打了基线,避免“玄学优化”。

1)跨境下载吞吐(iperf3)

客户端:北京云主机(电信 CN2)

服务端:香港源站(10G 口)

配置:iperf3 -c <HK_IP> -t 60 -P 8

指标 数值(Cubic)
平均吞吐 190–220 Mbps
重传率 1.5–2.2%
RTT(mtr 中位) 48–55ms

2)Web 端到端指标(30 分钟滚动)

指标 p50 p95
TTFB(动态 API) 210ms 620ms
首屏可交互(首屏图文) 1.2s 2.8s
下载 100MB 文件 6.8s 12.5s

备注:带宽没打满,延迟型卡顿明显,怀疑拥塞窗口在丢包后恢复太慢。

BBR 原理一句话(够用版)

Cubic 侧重“试探-回退”,在轻微丢包 + 中 RTT 场景会显得保守。BBR 则依据链路的 带宽-时延积(BDP) 建模,追求“以最小队列占用跑满可用带宽”。它需要准确的节拍(pacing),因此推荐结合 fq 队列规则 使用。

重点:BBR ≠ 降 RTT,它的强项是在丢包时保持高吞吐与短队列,应用层观感(TTFB、首屏)会显著改善。

实操步骤(Ubuntu 20.04)

下列命令需要 root 或 sudo 权限。

1. 确认内核版本与模块

uname -r
# 期望:5.4.x-xx-generic 或更高

# 查看是否有 bbr、cubic、reno 可用
sysctl net.ipv4.tcp_available_congestion_control
# 期望输出包含 bbr

# 如未包含,检查模块
lsmod | grep bbr || true
modprobe tcp_bbr  # 临时加载
lsmod | grep bbr

坑 1:缺少模块包

某些云镜像裁剪了 sch_fq 和 tcp_bbr 到 linux-modules-extra-* 包里。若 modprobe tcp_bbr 报 “Module not found”:

apt update
apt install -y linux-modules-extra-$(uname -r)
modprobe tcp_bbr

2. 启用 fq 队列 + BBR(持久化)

新建或编辑 /etc/sysctl.d/99-bbr.conf:

cat >/etc/sysctl.d/99-bbr.conf <<'EOF'
# 为 BBR 配置推荐的默认队列与拥塞控制
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# 可选:轻度优化缓冲/窗口(保守值,生产可逐步灰度)
net.ipv4.tcp_rmem = 4096 131072 6291456
net.ipv4.tcp_wmem = 4096 131072 6291456
net.ipv4.tcp_mtu_probing = 1
EOF

加载配置:

sysctl --system
sysctl net.core.default_qdisc
sysctl net.ipv4.tcp_congestion_control
# 期望:fq / bbr

验证 fq 是否生效(观察设备队列):

tc qdisc show dev eth0
# 期望有 "fq"(不是 fq_codel/codel)

坑 2:容器内无效

如果你是在 Docker/LXC 容器里改这些参数,最终起作用的是宿主机内核。容器里改好了不生效,请登录宿主机重复以上步骤。

3. 开机自动加载 BBR 模块(稳妥)

echo tcp_bbr >/etc/modules-load.d/bbr.conf

4.(可选)升级 HWE 内核

如果你想顺带获得更好的驱动/bugfix,可升级到 HWE 5.15:

apt install -y linux-generic-hwe-20.04
reboot
# 升级后重复第 1~3 步验证

5. 验证连接是否使用 BBR

新开一个跨境连接(例如从北京侧 curl 下载),在香港服务器上用 ss 看 TCP 信息:

ss -ti '( dport = :443 )'
# 看到 "cong bbr" 字样即为 BBR

也可以针对特定五元组过滤:

ss -ti dst <CLIENT_IP>

进阶:与 Nginx / 应用栈的配合

Nginx:无需特别改动;若有大文件下载,可开启 sendfile on; 并注意 tcp_nopush on;/tcp_nodelay on; 的配合(大对象走 sendfile,小对象走 nodelay)。

HTTP/2:BBR 改善的是内核侧 TCP 行为,对 H2 多路复用下的“队头阻塞”也有缓解(因为队列更短,丢包恢复更快)。

QUIC/HTTP/3:QUIC 使用用户态拥塞控制(与内核 TCP 无关),此文不展开。你的跨境主要仍是 TCP 流量时,BBR 收益更直接。

灰度与回滚

生产上我没有一把梭,按业务权重 逐台/逐池灰度:

先在一台边缘节点启用 BBR,观察 1–2 小时指标(重传率、TTFB p95、nginx upstream 响应分布、内核软中断占比)。

指标无回退扩大到半池。

需要回滚时仅需:

sysctl -w net.ipv4.tcp_congestion_control=cubic
# 或者把 99-bbr.conf 改回 cubic + fq_codel,再 sysctl --system

结果:启用 BBR 后的对比(同样 30 分钟窗口)

1)跨境吞吐(iperf3,相同参数)

指标 启用前(Cubic) 启用后(BBR) 变化
平均吞吐 190–220 Mbps 420–520 Mbps ↑ ~2.3×
重传率 1.5–2.2% 0.7–1.2% ↓ 40–60%
RTT(mtr 中位) 48–55ms 45–52ms 略降

RTT 本身变化不大,但队列占用更短,恢复更快。

2)Web 端到端(跨境用户)

指标 p50(前→后) p95(前→后) 变化
TTFB(动态 API) 210→150ms 620→260ms p95 ↓ ~58%
首屏可交互 1.2s→1.0s 2.8s→1.9s p95 ↓ ~32%
下载 100MB 6.8s→3.2s 12.5s→6.1s p95 ↓ ~51%

主观体验:页面“抽顿感”明显减少,视频起播更稳。

线上踩坑与解决

坑 A:fq 不可用(qdisc 显示 pfifo_fast 或 fq_codel)

现象:tc qdisc show dev eth0 没有 fq,sysctl net.core.default_qdisc=fq 也不生效。

原因:sch_fq 模块缺失或内核裁剪。

处理:apt install linux-modules-extra-$(uname -r),modprobe sch_fq,再 sysctl --system。

坑 B:云平台的“智能网卡加速”与 pacing 冲突

现象:启用 BBR 后吞吐无提升,甚至更差。

定位:X710 开了某些 offload(如过 aggressive 的 TSO/GRO/LLC 组合)与 pacing 掐架。

处理:用 ethtool -k eth0 查看,适度关闭/开启:

ethtool -K eth0 gso on gro on tso on # 大多数情况保留
# 若异常,可尝试逐项 off 验证

坑 C:容器 / 宿主机混淆

现象:容器里显示 bbr,但跨机测试无提升。

原因:实际走的是宿主机 TCP 栈,容器设置不起作用。

处理:到 宿主机 配置 BBR。

坑 D:队列过大引起尾延迟

现象:BBR 后 p95 TTFB 仍然高。

排查:/proc/net/softnet_stat 里 dropped 升高,网卡队列/中断抢占不合理。

处理:适当调小 txqueuelen/RPS/RFS,均衡 IRQ 亲和;示例:

ip link set eth0 txqueuelen 2000
# irqbalance 开启,必要时手动做 CPU 亲和

我实际采用的保守型内核参数(供参考)

不同业务要 A/B:不要一次性全开。下面是我在源站上的“稳妥集”。

# /etc/sysctl.d/99-bbr.conf(附加)
net.core.somaxconn = 1024
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 10000 65535
net.core.netdev_max_backlog = 250000
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608

一键自检脚本(上线前后都能跑)

把下面的脚本存为 check_bbr.sh:

#!/usr/bin/env bash
set -e

echo "== Kernel =="
uname -a

echo "== Congestion Control =="
sysctl net.ipv4.tcp_congestion_control
sysctl net.ipv4.tcp_available_congestion_control

echo "== Default qdisc =="
sysctl net.core.default_qdisc
tc qdisc show dev eth0 || true

echo "== Modules =="
lsmod | egrep 'bbr|sch_fq' || true

echo "== Nginx (if any) =="
ps aux | grep -E '[n]ginx' || echo "nginx not running"

echo "== Sample active TCP (first 5) =="
ss -ti '( dport = :443 )' | head -n 50 || true

echo "== Done =="

执行:

chmod +x check_bbr.sh
./check_bbr.sh

FAQ:几个常见问题

Q1:BBR 会不会对本地(香港本地/东南亚)用户变差?
一般不会,BBR 会维持较短的排队延迟;若本地用户极少丢包,体验通常不受影响或略好。

Q2:fq 和 fq_codel 选哪个?
BBR 官方推荐 fq,因为它支持精确 pacing;fq_codel 主打控延迟,但与 BBR 的节拍目标略不同。跨境吞吐 + 端到端延迟观感,我在实测里更偏 fq。

Q3:怎么只给一台/一组业务启用?
拥塞控制是 系统级 的;若要对特定业务做不同策略,建议用独立主机或 VM。

结尾:凌晨 3 点的机房走廊

启用 BBR 的 20 分钟后,前端的 p95 TTFB 从 600ms 掉到了 300ms 以下,下载速度也稳定翻倍。

我在机房走廊上伸了个懒腰,空调的风有点冷,但心是热的。

第二天白天,客服群里没了“卡顿”的抱怨,多了几句“昨天怎么突然好快”。这事儿没人会记很久,但作为运维,我知道,这一夜我们把链路的潜力又榨出了几分。

Checklist(拿去即用)

  •  uname -r ≥ 4.9(Ubuntu 20.04 默认 OK)
  •  linux-modules-extra-$(uname -r) 已安装
  •  /etc/sysctl.d/99-bbr.conf:default_qdisc=fq、tcp_congestion_control=bbr
  •  sysctl --system 后验证:tc qdisc show dev eth0 有 fq
  •  ss -ti 确认活跃连接 cong bbr
  •  逐台灰度,上线 30–60 分钟观察 p95 TTFB/重传率/CPU 软中断
  •  准备回滚命令:sysctl -w net.ipv4.tcp_congestion_control=cubic

如果你也在香港或其他跨境节点折腾网络体验,不妨按这套流程先跑一轮基线,再上 BBR 做 A/B。优化的尽头是度量——愿我们少点玄学,多点确定性

目录结构
全文