Ubuntu 22.04开启BBR
开启BBR
Ubuntu 22.04 自带 5.15 内核,BBR(v1)模块是内置的,只需改两行 sysctl 就能开启,不需要升级内核。
一、检查前置条件
uname -r # ≥4.9 即可,22.04 一般是 5.15.x
cat /proc/sys/net/ipv4/tcp_available_congestion_control # 输出里能看到 bbr 就说明模块可用
如果第二条的返回结果里没有 bbr,先手动加载模块再看:
sudo modprobe tcp_bbr
二、开启 BBR(推荐用独立配置文件,不污染 sysctl.conf)
cat <<'EOF' | sudo tee /etc/sysctl.d/99-bbr.conf
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF
sudo sysctl --system
fq(Fair Queue)是必须的配套项:BBR 依赖它做发送速率的 pacing 调度。换成fq_codel也能跑(新版内核已支持 pacing),但效果不如fq匹配。
三、保证重启后仍生效
多数情况下内核会自动按需加载模块,保险起见显式配置一下:
echo "tcp_bbr" | sudo tee /etc/modules-load.d/bbr.conf
四、验证
sysctl net.ipv4.tcp_congestion_control # 期望: bbr
sysctl net.core.default_qdisc # 期望: fq
lsmod | grep bbr # 期望: tcp_bbr 条目
ss -tin # 单条连接详情里能看到 bbr 及其带宽/RTT 估算
几个容易踩的点
- BBRv1 对丢包敏感:在丢包率高(>1%~2%)的链路上 BBRv1 反而会激进发包导致吞吐下降;若是弱网/高丢包场景,可以回头对比
cubic实测一下。Ubuntu 22.04 的 5.15 内核只有 BBRv1,BBRv2/v3 需要自行换 6.x 主线内核。 - 云服务器:部分厂商自定义镜像会裁剪掉
tcp_bbr模块,此时modprobe会报Module not found,需要换成官方内核镜像。 - 容器/虚拟机:BBR 是主机内核级参数,容器内改无效,要在宿主机上设置;KVM/OpenVZ 类 VPS 中 OpenVZ 无法自行开启。
- 生效范围:仅影响 TCP 出站拥塞控制,对 UDP(QUIC 等)无效。
切换回CUBIC
不用重启,两条命令就能切回去。
一、临时切回(想先快速验证效果)
sudo sysctl -w net.ipv4.tcp_congestion_control=cubic
sudo sysctl -w net.core.default_qdisc=fq_codel
立即生效,但重启后会回到配置文件里的值。适合先做个快速 A/B 对比。
二、永久切回(确定不用 BBR 了)
直接删掉之前那两个配置文件,让系统回到默认状态:
sudo rm -f /etc/sysctl.d/99-bbr.conf
sudo rm -f /etc/modules-load.d/bbr.conf
sudo sysctl --system
删除后 sysctl --system 会重新加载全部配置,tcp_congestion_control 回落到内核编译默认值(Ubuntu 就是 cubic),default_qdisc 回到 fq_codel。
如果你不想删文件、只想"关掉留着配置",也可以把
/etc/sysctl.d/99-bbr.conf里的bbr改成cubic、fq改成fq_codel,然后sudo sysctl --system。效果一样,方便以后再切回来。
关于 qdisc:建议一并换回 fq_codel
fq 是给 BBR 做发送 pacing 用的,cubic 并不需要它。而 Ubuntu 默认的 fq_codel 自带抗 bufferbloat 能力,能压低排队延迟——对 Web 服务器(大量并发短连接)反而比 fq 更合适。
所以回滚时两个参数都要改,只改拥塞控制、留着 fq 也能跑,但拿不到 fq_codel 的延迟优化。
三、验证
sysctl net.ipv4.tcp_congestion_control # 期望: cubic
sysctl net.core.default_qdisc # 期望: fq_codel
lsmod | grep bbr # 可以还残留 tcp_bbr 模块,无影响
ss -tin # 新建连接应显示 cubic / cwnd / ssthresh
lsmod 里还有 tcp_bbr 不用管——模块只是被加载进内存,没有连接使用它就完全不占资源,重启后自然消失。
两个关键提醒
1. 已建立的长连接不会立刻切换
和开 BBR 时一样:算法在连接建立时就绑定了。改完参数后,新建的连接走 cubic,之前的长连接仍然跑在 BBR 上直到断开。要彻底清干净,重启相关服务即可(不用重启机器):
sudo systemctl restart nginx # 或 apache2 / 你的应用服务
2. 趁机做个前后对比
既然是怀疑 BBR 导致效果不好才回滚,建议留一组数据再改,否则过几天就分不清了。重点记三个数:
nstat -az | grep -i retrans # 重传率,BBRv1 劣化时这个会飙升
ss -tin # 看 cwnd / rtt 健康度
再结合业务监控的 P95/P99 响应时间和 5xx 错误率。如果切回 cubic 后重传率明显下降、尾延迟改善,那就基本坐实是 BBRv1 在你的链路上水土不服,可以放心长期留在 cubic;如果两个算法几乎没差别,说明你的瓶颈本来就不在拥塞控制上,得往带宽、应用耗时或 CDN 那几个方向查。