跳到主要内容

网络优化 · 已发布教程

BBR 拥塞控制:系统支持、配置生效范围与核对方法

发布 更新 阅读约 8 分钟酷主机编辑部

分开核对 Linux TCP 的已注册算法、新连接默认值、实际连接与接口队列,理解配置项说明、运行时应用和启动加载的区别,并建立可恢复的验证记录。

先确认内核、工具和 BBR 实现范围

本文检查 Linux 内核的 TCP 拥塞控制。BBR 根据连接的交付速率和往返时延等信息调整发送行为;Google 项目另有 QUIC 实现,不能把 Linux TCP 的设置直接当作所有协议的统一开关。

先记录正在运行的内核版本和 ss 工具版本,再对照发行版提供的内核包、构建配置或源码说明。uname -r 只显示运行内核的版本标识,不单独证明该内核包含哪一代 BBR 或哪些回移补丁。

本文引用 Linux v6.12 与 iproute2 v6.12.0 作为可复查的版本基线,不要求服务器恰好运行这两个版本。Google 的 BBRv3 发布说明面向研究协作和扩大测试,其示例同样使用 bbr 这个算法名;仅看到 bbr,不能据此确认 BBRv3。

记录运行内核与 ss 版本 · 只读检查 · 仅限审查只输出运行内核和本机工具的版本,不安装软件、不加载模块、不更换内核。 如内容超出,可左右滑动,键盘使用方向键或 Home/End 查看。
仅复制文本,不会执行。
uname -r
ss -V

分开读取已注册算法、允许范围和默认值

tcp_available_congestion_control 列出当前已注册的拥塞控制算法。内核文档明确说明,还可能存在尚未加载的算法模块,因此列表中没有 bbr 时,应先核对内核构建与模块提供情况,不能直接认定系统永远不支持。

tcp_allowed_congestion_control 是非特权进程可以选择的算法范围,属于已注册算法的子集;它不是当前所有连接所用算法的清单。tcp_congestion_control 则选择新连接的默认算法,默认值取决于内核配置。

被动建立的连接会继承监听 socket 的拥塞控制选择,应用也可以通过 TCP_CONGESTION 选择算法。因此,读取到默认值 bbr 只是其中一层证据,不能代替对既有连接或具体服务的检查。

读取 TCP 拥塞控制的三个配置视角 · 只读检查 · 仅限审查只读取三个 sysctl 参数;命令不带赋值、不应用配置文件,也不加载算法模块。 如内容超出,可左右滑动,键盘使用方向键或 Home/End 查看。
仅复制文本,不会执行。
sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_allowed_congestion_control
sysctl net.ipv4.tcp_congestion_control

从实际 TCP 连接核对算法和状态

使用 ss -tin 查看 TCP 套接字及内部信息:-t 选择 TCP,-i 请求内部状态,-n 保留数字形式的地址和端口。先用目标服务的地址与端口找到对应连接,再查看它显示的拥塞控制算法,不要把其他连接的结果移用到目标业务。

Google BBR FAQ 说明,具备相应显示能力的 ss 可以输出 BBR 的 pacing rate、拥塞窗口、带宽估计和最小 RTT 估计等状态。这些字段描述被观察连接的内部状态,不是套餐带宽、持续吞吐或跨地域性能结论。

没有目标连接时,先在获准的业务验证中建立连接,再读取状态。缺少 BBR 详细字段时应核对内核与 ss 的支持情况;默认值、监听 socket 选择和实际连接需要分别记录,不能只凭一条 sysctl 输出宣布检查完成。

查看实际 TCP 连接及内部状态 · 只读检查 · 仅限审查只读取已有 TCP 套接字状态;命令不会主动建立连接、发起压测或更改算法。 如内容超出,可左右滑动,键盘使用方向键或 Home/End 查看。
仅复制文本,不会执行。
ss -tin

把默认队列设置与接口实际队列分开

net.core.default_qdisc 表示网络设备的默认队列规则,不等于每个接口正在使用的完整队列结构。先读取默认设置,再通过 tc -s -d qdisc show 查看实际接口的队列、详细参数与统计。

Linux v6.12 文档说明,多队列物理接口会使用 mq 根队列,并把默认规则用于其叶节点;lo、veth 等虚拟设备会忽略该默认规则而使用 noqueue。因此,不能仅凭出现 mq 或 noqueue 就判断 BBR 无效。

Linux v6.12 的 BBR 源码说明,它可以使用 fq 提供的 pacing;否则 TCP 使用内部 pacing,可能带来更多资源开销。这个结论有明确版本范围,不能将某个旧版本的队列要求直接套用到所有内核。

队列统计用于理解当前接口,不直接代表端到端丢包率。已有整形、QoS 或多队列策略时,应先确认业务所经接口与配置负责人,再单独评审队列变更,不把替换根队列作为启用 BBR 的固定附带动作。

读取默认 qdisc 与接口实际队列 · 只读检查 · 仅限审查只读取 sysctl 和队列统计,不增加、删除或替换任何接口的 qdisc。 如内容超出,可左右滑动,键盘使用方向键或 Home/End 查看。
仅复制文本,不会执行。
sysctl net.core.default_qdisc
tc -s -d qdisc show

理解配置项、运行时应用与启动加载

真实配置项 net.ipv4.tcp_congestion_control = bbr 的含义,是把新连接的默认 TCP 拥塞控制选择设为 bbr;采用它之前,需要确认本机算法支持、服务的 socket 选择和具体变更范围。下面保留注释来解释该配置项,不是已生效配置,也不会启用设置。

运行时写入、保存配置文件和开机加载是三个不同步骤。procps-ng 的 sysctl 可读取或写入运行时参数;sysctl -p 与 sysctl --system 会加载并应用配置,不能当成只读检查命令。写过运行时值,也不等于重启后一定保留。

采用 systemd-sysctl 的系统会在启动阶段读取 sysctl.d 配置。先确认实际发行版使用的加载器、文件目录与服务配置,再检查同名文件优先级和按文件名字典序产生的覆盖。systemd v257 的规则与 procps-ng sysctl --system 的加载路径不应混为一谈,尤其后者还会在最后读取 /etc/sysctl.conf。

评审时记录原运行时值、原配置文件及其来源、覆盖关系和服务选择方式。按实际发行版流程应用后,重新读取默认值并检查新建业务连接;如果需要验证启动加载,应在已批准的维护窗口和恢复条件下单独验证,不能以文件存在代替生效证据。

恢复时应还原此前记录的实际配置和默认值,并处理本次新增或修改的持久化条目,再重新核对服务连接。不要把 cubic 写成所有环境的固定回退值;接口队列应按其实际结构单独评审,不与算法选择捆绑修改。

BBR 配置项说明 · 离线审查 · 不可执行所有行均为注释,用于解释真实配置项;复制不会应用设置,实际写入与加载配置须另行按发行版流程评审。 如内容超出,可左右滑动,键盘使用方向键或 Home/End 查看。
仅复制文本,不会执行。
# 配置项说明;保持注释,不会改变系统设置。
# net.ipv4.tcp_congestion_control = bbr

分别验证配置生效与业务效果,并保留恢复记录

把检查记录组织成可复核的顺序:先保存内核与工具版本、原算法、目标连接和接口队列,再确认控制台与维护窗口;变更后重新读取默认值、检查新建业务连接,并记录实际采用的算法。只改变已评审的目标项,避免把内核、队列和业务配置同时变化后的结果归因于 BBR。

业务效果需要独立对照:记录相同业务场景下的连接方向、并发、数据量、时间窗口与端点条件,再比较实际吞吐、响应时间和重传等观察值。配置生效不等于业务改善,单次连接的带宽估计也不能代替持续观察。

如需在隔离环境模拟网络条件,应先设计测试拓扑。Google BBR FAQ 指出,把 netem 放在发送端会受到 TCP small queues 等机制影响,导致不真实的 TCP 性能结果;不能直接把未经核对的丢包模拟脚本当作生产网络表现。

若目标服务未采用预期算法、启动加载没有保持预期设置或业务指标退化,应停止扩大变更,按记录恢复实际原值和持久化配置,再用新连接复核。需要判断端口可达性时可继续阅读 UFW 检查教程;防火墙状态与拥塞控制是不同检查对象。