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

如何安全调整香港服务器Linux内核的TCP拥塞控制、BBR与高并发连接参数?

发布人:Minchunlin 发布时间:2026-10-07 15:22 阅读量:6

在香港服务器上调整 Linux 内核网络参数,目标不应是一次性把 BBR、队列、文件描述符和连接数全部调到很大的数值,而是让新建 TCP 连接能够使用合适的拥塞控制算法,并让监听队列、进程句柄和系统资源与实际并发规模匹配。生产变更的核心是:先确认当前内核和业务边界,再分批应用参数,最后用真实业务流量观察,并为每一步保留可执行的回滚路径。

BBR 是否适用,取决于内核是否提供 BBR、队列规则是否支持合理的发送节奏,以及香港服务器到实际访问区域的链路质量。高并发连接也不只是修改 somaxconn:内核文件句柄、systemd 服务限制、Nginx 或应用自身的连接上限、内存、CPU 软中断和云厂商网络限制都可能成为瓶颈。因此,以下方案采用“现状核对—变更准备—分步实施—验证观察—回滚”的生产变更顺序,不默认读者环境已经执行成功。

现状核对:先确认内核、业务和流量边界

识别操作系统与内核能力

BBR v1 在较新的 Linux 内核中提供,但不同发行版可能对内核功能进行了回移植,不能只根据版本号判断。应以当前系统实际暴露的拥塞控制算法列表为准。

cat /etc/os-release
uname -r
uname -m

sysctl -n net.ipv4.tcp_available_congestion_control
sysctl -n net.ipv4.tcp_congestion_control
sysctl -n net.core.default_qdisc

modinfo tcp_bbr 2>/dev/null || true
lsmod | grep -E '(^| )tcp_bbr( |$)' || true

如果 tcp_available_congestion_control 中没有 bbr,先不要直接把 net.ipv4.tcp_congestion_control 写成 bbr。这通常意味着当前内核没有加载对应模块、模块包不完整,或者云平台提供的内核不允许使用该算法。此时应先确认发行版内核包和云平台限制,不建议在同一个生产窗口内临时升级内核并同时调整网络参数。

如果服务器运行在容器内,uname -r 和 TCP 拥塞控制算法通常由宿主机内核决定。容器内即使有 root 权限,也可能不能修改相关 sysctl 或加载模块,应由宿主机管理员处理。

区分监听连接、出站连接和已建立连接

高并发场景至少要区分三类资源:

现状核对:先确认内核、业务和流量边界配图

  • 监听端口上的入站连接:重点关注 somaxconn、tcp_max_syn_backlog、应用 listen backlog、进程文件句柄和内存。
  • 服务器主动发起的出站连接:重点关注 ip_local_port_range、TIME_WAIT、连接复用和上游服务响应。
  • 已经建立的长连接:重点关注每连接内存、文件句柄、应用事件循环、心跳和空闲连接清理。

net.ipv4.ip_local_port_range 主要解决本机主动发起连接时的临时端口范围问题,并不会直接增加服务器监听端口能够接受的入站连接数。不要因为入站连接数较多,就直接修改临时端口范围。

先保存当前连接和监听状态:

ss -s
ss -lntp
ss -ant state syn-recv | wc -l
ss -ant state established | wc -l

sysctl -n net.core.somaxconn
sysctl -n net.ipv4.tcp_max_syn_backlog
sysctl -n net.ipv4.ip_local_port_range
sysctl -n fs.file-max
sysctl -n fs.nr_open

如果系统安装了 nstat,还可以查看 TCP 扩展统计:

nstat -az | egrep 'TcpRetransSegs|TcpExtListenOverflows|TcpExtListenDrops|TcpExtTCPTimeouts|TcpExtTCPAbort'

不同发行版的 nstat 输出名称可能略有差异。也可以直接保留 /proc/net/netstat 作为变更前快照,之后比较计数器增量:

grep -E '^(Tcp:|TcpExt:)' /proc/net/netstat

ListenOverflows 和 ListenDrops 是累计计数,不应只看绝对值。更有意义的是在相同观察周期内比较变更前后的增长速度。

核对服务和文件描述符上限

内核允许的文件句柄数量,不代表业务进程就能使用同样多的文件描述符。systemd 服务限制、Nginx 的 worker_rlimit_nofile、worker_connections,以及应用框架自身的连接池上限,都必须同时满足。

以 Nginx 为例,先核对服务限制和实际进程限制:

systemctl show nginx -p LimitNOFILE 2>/dev/null || true

NGINX_PID=$(pgrep -o nginx || true)
if [ -n "$NGINX_PID" ]; then
    grep 'open files' "/proc/$NGINX_PID/limits"
fi

nginx -T 2>/dev/null | grep -E 'worker_rlimit_nofile|worker_connections|listen ' || true

如果实际业务不是 Nginx,应替换为对应服务名和进程。一个反向代理进程可能同时持有客户端连接、上游连接、日志文件、监听套接字和内部管道,因此不能简单地用“并发连接数等于文件描述符数量”进行容量估算。

A5数据提供香港物理服务器租用,涵盖Xeon Gold与AMD EPYC等平台,以多档CPU、内存及SSD、NVMe存储组合,为高并发网站、接口服务、业务后台和数据库提供计算与数据承载基础。香港产品另有CN2与国际带宽方案,衔接不同访问区域的网络需求,让Linux连接承载能力与TCP拥塞控制调整拥有相应的硬件和线路资源基础。

变更准备:备份、分批和执行窗口

明确本次变更不处理的内容

首次调整建议只处理三组参数:

  1. BBR 可用性、默认拥塞控制算法和队列规则。
  2. 监听队列相关参数。
  3. 文件描述符和应用服务限制。

以下参数不要在同一批次中顺手修改:

  • net.ipv4.tcp_rmem、net.ipv4.tcp_wmem 的大范围上调;
  • net.ipv4.tcp_fin_timeout;
  • net.ipv4.tcp_tw_reuse;
  • net.ipv4.tcp_max_tw_buckets;
  • net.core.netdev_max_backlog;
  • 防火墙、连接跟踪和网卡中断参数;
  • 内核版本、网卡驱动和云平台网络配置。

这些参数可能影响内存占用、连接回收、出站端口复用或软中断处理,适合在有独立基线和专门测试的变更中处理。特别是 tcp_tw_reuse,不能作为“高并发通用开关”直接启用。

选择执行窗口和回滚入口

生产变更至少应满足以下条件:

  • 有云平台控制台、带外终端或其他不依赖当前业务网络的登录入口;
  • 已确认当前 SSH 或远程管理连接不会因参数变更被主动中断;
  • 单节点业务已准备维护页、流量摘除或备用节点;
  • 多节点业务先选一台容量和流量较小的节点做灰度;
  • 变更期间有人持续观察错误率、延迟、连接数和系统资源;
  • 已确定停止变更和回滚的负责人,不在异常发生后临时讨论方案。

BBR 和默认 TCP 拥塞控制主要影响新建连接,已有连接通常不会立即切换。因此,观察窗口不能只安排几分钟后就结束。短连接业务需要观察新建连接比例,长连接业务还要关注旧连接与新连接混合存在时的表现。

保存配置与关键状态

以下示例使用时间戳建立独立备份目录。执行前应确认磁盘空间和目录权限。

TS=$(date +%Y%m%d-%H%M%S)
BACKUP="/root/tcp-tuning-backup-${TS}"

install -d -m 700 "$BACKUP"

[ -f /etc/sysctl.conf ] && cp -a /etc/sysctl.conf "$BACKUP/"
[ -d /etc/sysctl.d ] && cp -a /etc/sysctl.d "$BACKUP/"

sysctl -a > "$BACKUP/sysctl-before.txt" 2>&1
ss -s > "$BACKUP/ss-before.txt"
ss -lntp > "$BACKUP/ss-listen-before.txt"
grep -E '^(Tcp:|TcpExt:)' /proc/net/netstat > "$BACKUP/netstat-before.txt"

sysctl -n net.core.default_qdisc > "$BACKUP/default_qdisc"
sysctl -n net.ipv4.tcp_congestion_control > "$BACKUP/tcp_congestion_control"
sysctl -n net.core.somaxconn > "$BACKUP/somaxconn"
sysctl -n net.ipv4.tcp_max_syn_backlog > "$BACKUP/tcp_max_syn_backlog"
sysctl -n fs.file-max > "$BACKUP/fs.file-max"
sysctl -n net.ipv4.ip_local_port_range > "$BACKUP/ip_local_port_range"

systemctl show nginx -p LimitNOFILE > "$BACKUP/nginx-limitnofile.txt" 2>/dev/null || true

如果系统中原本已经存在多个 sysctl 配置文件,必须先检查同一个参数是否被重复定义:

grep -RnsE 'net\.core\.default_qdisc|net\.ipv4\.tcp_congestion_control|net\.core\.somaxconn|net\.ipv4\.tcp_max_syn_backlog|fs\.file-max|ip_local_port_range' \
    /etc/sysctl.conf /etc/sysctl.d 2>/dev/null || true

后加载的配置可能覆盖先加载的配置。不要只修改一个文件,却忽略 /etc/sysctl.d/ 中已有的同名设置。

参数设计:给出范围,不直接套用固定数值

下表中的数值是便于说明的示例起点,不代表所有香港服务器都应使用相同配置。实际值不能低于当前已有值,也不能脱离内存、连接模型和应用限制单独放大。

参数作用示例起点主要风险与核对点
net.ipv4.tcp_congestion_control新建 TCP 连接的默认拥塞控制算法bbr必须先确认算法可用;不影响所有已有连接
net.core.default_qdisc新建网络设备的默认队列规则fq只写 sysctl 不代表当前网卡队列已切换
net.core.somaxconn应用已完成握手、等待 accept 的队列上限4096受应用 listen(backlog) 实际值约束
net.ipv4.tcp_max_syn_backlog尚未完成握手的 SYN 队列上限8192需要结合突发连接、SYN Cookie 和内存观察
fs.file-max系统级文件句柄上限2097152不是进程上限,过大也不能替代内存规划
net.ipv4.ip_local_port_range本机主动连接使用的临时端口范围按业务决定只针对出站连接,需检查端口保留和连接复用

somaxconn 与 tcp_max_syn_backlog 解决的是不同阶段的问题。前者偏向已经完成 TCP 握手但应用还未及时 accept 的连接,后者偏向握手尚未完成的连接。两者调大并不能自动提高应用处理能力,也不能替代进程文件描述符和应用连接池配置。

如果当前值已经高于示例值,不应为了统一配置而降级。例如当前 somaxconn=8192,就不要在候选文件中写入 4096。对于 fs.file-max,也应结合当前句柄使用量、物理内存和服务数量评估,而不是仅按照一个很大的整数设置。

分步实施:先 BBR,再连接承载能力

第一步:确认并加载 BBR 模块

先检查当前列表中是否已经有 BBR:

grep -qw bbr /proc/sys/net/ipv4/tcp_available_congestion_control \
    && echo "BBR is available" \
    || echo "BBR is not available"

如果没有,尝试加载模块:

modprobe tcp_bbr

sysctl -n net.ipv4.tcp_available_congestion_control
lsmod | grep -E '(^| )tcp_bbr( |$)' || true

如果加载后仍没有 bbr,应停止本次 BBR 变更,保留原有算法,不要继续写入配置。需要升级内核时,应另行安排内核变更、重启和启动失败回滚。

确认 BBR 可用后,再建立独立的候选配置文件:

cat >/etc/sysctl.d/98-a5idc-bbr-canary.conf <<'EOF'
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF

只应用这个文件,不要直接执行会扫描所有配置的命令:

sysctl -p /etc/sysctl.d/98-a5idc-bbr-canary.conf

然后检查内核当前值:

sysctl -n net.core.default_qdisc
sysctl -n net.ipv4.tcp_congestion_control
sysctl -n net.ipv4.tcp_available_congestion_control

default_qdisc=fq 主要表示后续创建网络设备时使用的默认队列规则。当前网卡是否已经采用 fq,必须单独查看。先根据实际业务目的地确定出口接口:

DEST_IP="填写业务实际探测IP"
IFACE=$(ip route get "$DEST_IP" | awk '
{
    for (i = 1; i <= NF; i++) {
        if ($i == "dev") {
            print $(i + 1)
            exit
        }
    }
}')

echo "$IFACE"
tc -s qdisc show dev "$IFACE"

如果当前网卡已经显示 qdisc fq,可以继续观察。如果显示的是其他队列规则,不要在高峰期直接替换。tc qdisc replace dev ... root fq 属于独立的网卡队列变更,可能影响发送队列,必须记录原队列类型、安排更明确的维护窗口,并准备按原类型恢复。仅仅把 sysctl 写成 fq,不能假设现有接口已经完成替换。

确认 BBR 运行稳定后,再决定是否持久化模块加载:

if modinfo tcp_bbr >/dev/null 2>&1; then
    printf '%s\n' tcp_bbr >/etc/modules-load.d/tcp-bbr.conf
fi

如果 BBR 是内核内建功能而不是模块,不需要为了形式而创建该文件。回滚时也不要强制卸载正在被连接使用的模块;移除持久化配置即可,模块可在下次重启后自然恢复原状态。

第二步:应用监听队列和系统句柄参数

BBR 至少观察一个短周期且确认没有异常后,再应用连接承载能力参数。候选配置如下:

cat >/etc/sysctl.d/99-a5idc-concurrency-canary.conf <<'EOF'
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
fs.file-max = 2097152
EOF

在应用前再次对照备份和当前值,确认没有把现有较大值覆盖成较小值。确认后执行:

sysctl -p /etc/sysctl.d/99-a5idc-concurrency-canary.conf

检查是否生效:

sysctl -n net.core.somaxconn
sysctl -n net.ipv4.tcp_max_syn_backlog
sysctl -n fs.file-max

ss -lntp
ss -ant state syn-recv | wc -l

如果某个参数在当前内核不存在,sysctl 会报错。此时不应为了消除报错而猜测参数名称,也不要把其他相似参数强行替换进去。记录错误并根据发行版和内核文档核对。

第三步:同步调整服务级文件描述符

只有系统级 fs.file-max 增大时,业务进程仍可能保持原有较低限制。以 systemd 管理的 Nginx 为例,可以先创建服务覆盖文件:

install -d -m 755 /etc/systemd/system/nginx.service.d

cat >/etc/systemd/system/nginx.service.d/limits.conf <<'EOF'
[Service]
LimitNOFILE=200000
EOF

systemctl daemon-reload
systemctl show nginx -p LimitNOFILE

该限制通常需要重新创建服务进程才能生效。单节点生产环境不要未经维护窗口直接重启;多节点环境应先将一台节点摘出流量,确认健康检查通过后再处理。

Nginx 配置中的连接数也必须与文件描述符上限匹配,示例位置如下:

worker_rlimit_nofile 200000;

events {
    worker_connections 100000;
}

修改前应备份原配置,并先检查语法:

cp -a /etc/nginx/nginx.conf "/root/tcp-tuning-backup-${TS}/nginx.conf.before"

nginx -t

worker_connections 不是整个服务器的总连接数保证值。反向代理场景中,一个客户端连接可能对应一个上游连接,日志、监听套接字和其他文件也会占用句柄。配置数值必须结合 worker 数量、应用模型、内存和真实连接关系确定。

分步实施:先 BBR,再连接承载能力配图

如果只是修改 Nginx 配置,通常可使用:

systemctl reload nginx

如果修改了 systemd 的 LimitNOFILE,则需要按业务拓扑安排受控重启,使新的进程继承该限制。不能用 reload 代替进程重建,也不要为了应用一个句柄限制在单节点上无计划重启。

第四步:谨慎处理出站临时端口

只有在服务器主动创建大量短连接、出现临时端口耗尽,或者明确存在出站连接端口瓶颈时,才评估 ip_local_port_range。先看当前范围和端口使用情况:

sysctl -n net.ipv4.ip_local_port_range
ss -tan state time-wait | wc -l
ss -tan state established | wc -l

扩大范围前,要确认没有端口保留规则、应用固定绑定端口或安全策略冲突。不要为了“高并发”直接同时调整 tcp_fin_timeout、TIME_WAIT 回收和临时端口范围。短连接数量异常时,应先检查连接复用、上游响应时间、应用超时和连接池,而不是只扩大端口范围。

验证观察:以新建连接和真实流量为准

立即验证配置状态

每完成一个阶段,都应记录实际生效值和服务状态:

sysctl -n net.ipv4.tcp_congestion_control
sysctl -n net.core.default_qdisc
sysctl -n net.core.somaxconn
sysctl -n net.ipv4.tcp_max_syn_backlog
sysctl -n fs.file-max

systemctl is-active nginx 2>/dev/null || true
ss -s
ss -lntp
tc -s qdisc show dev "$IFACE"

BBR 是新建 TCP 连接的默认算法,不要只观察变更前已经建立的长连接。可以在受控条件下新建少量业务连接,再结合 ss -tin 观察 TCP 信息:

ss -tin | grep -Ei 'bbr|cubic' || true

不同内核和 iproute2 版本的输出字段不完全相同,不能仅凭一条空结果判断 BBR 失败。应同时确认 tcp_congestion_control、可用算法列表以及实际新建连接的状态。

观察网络、系统和应用三个层面

建议至少同时记录以下指标:

层面观察项异常含义
应用HTTP 状态码、连接超时、TLS 握手失败、上游错误参数变更可能放大排队或资源争用
TCP重传、超时、SYN-RECV、ListenDrops、ListenOverflows链路质量、队列、应用 accept 能力或突发连接存在问题
系统CPU、软中断、内存、swap、文件句柄使用率并发提高后资源未跟上
网卡队列tc -s qdisc 的丢包、排队和发送统计队列规则或出口带宽出现瓶颈
云平台带宽、pps、连接数、流量策略告警可能触及实例规格或平台限制

可以使用以下命令进行短周期观察:

watch -n 5 '
echo "=== socket ==="
ss -s
echo "=== listen ==="
ss -lnt
echo "=== tcp counters ==="
nstat -az 2>/dev/null | egrep "TcpRetransSegs|TcpExtListenOverflows|TcpExtListenDrops|TcpExtTCPTimeouts" || true
'

watch 适合临时观察,不适合作为长期监控。生产环境应将这些指标纳入已有监控系统,并记录变更前同一时段的基线。

验证应从实际访问来源进行,包括香港本地、主要用户区域,以及 IPv4 和 IPv6(如果业务同时开放)。本机 curl 成功只能说明本机路径和本地服务正常,不能代表外部链路上的 TCP 重传、握手延迟和带宽表现。

设计受控流量验证

如果需要压测,应使用与生产协议、响应大小和连接复用方式接近的工具,并控制并发、持续时间和来源范围。不要在没有限速和停止条件的情况下直接对公网端口发起大规模测试。

一次有效的对比至少要保持以下条件一致:

  • 相同的请求 URL、响应大小和连接复用策略;
  • 相同或相近的并发连接数;
  • 相同的测试来源区域和协议版本;
  • 相同的业务节点、带宽规格和时间段;
  • 同时记录 p50、p95 延迟、错误率、重传和 CPU。

BBR 带来的结果不能只用单次吞吐量判断。香港服务器与不同访问区域之间的 RTT、丢包、带宽整形和高峰拥塞可能变化较大。若吞吐提升同时伴随重传率、延迟或其他业务错误上升,不能将其视为成功。

回滚条件与执行路径

建议立即停止或回滚的条件

以下条件满足任一项,就应暂停继续调参,并根据影响范围执行回滚:

  • BBR 不在可用算法列表中,或模块加载失败;
  • 新建连接出现明显超时、握手失败或连接重置;
  • HTTP 5xx、上游超时或 TLS 错误率较基线持续升高;
  • p95 延迟在相同流量下持续恶化;
  • ListenOverflows、ListenDrops 在观察周期内明显增加;
  • TCP 重传、超时或软中断丢包持续增加;
  • 文件句柄接近服务限制,出现 too many open files;
  • 内存压力、swap、OOM 或系统负载明显升高;
  • 云平台出现带宽、pps 或连接数限制告警;
  • 队列规则切换后出现发送异常、丢包或业务连接不稳定。

数值阈值应结合业务基线制定。没有历史基线时,可以把“同等流量下错误率不升高、延迟不持续恶化、关键累计计数器增长速度不明显加快”作为第一层判断;高并发核心业务则应预先约定更严格的百分比和持续时间,例如连续多个采样周期恶化即触发回滚,而不是等待资源完全耗尽。

回滚顺序

回滚应优先恢复业务可用性,再清理持久化配置:

回滚条件与执行路径配图

  1. 停止继续增加参数,必要时先将异常节点摘出流量。
  2. 如果刚修改了 Nginx 或应用配置,先恢复原配置并执行语法检查。
  3. 恢复 systemd 的文件描述符覆盖文件,按节点拓扑受控重启服务。
  4. 恢复 sysctl 的运行时值。
  5. 如果曾单独替换网卡队列,按变更前记录恢复原队列规则。
  6. 删除本次新增的持久化配置,并确认下次启动不会再次应用异常参数。
  7. 重新检查监听、连接、错误率和系统资源,确认回滚本身没有引入新问题。

如果本次只创建了两个候选文件,可以使用备份值恢复运行时参数:

restore_sysctl() {
    KEY="$1"
    FILE="$2"

    if [ -s "$FILE" ]; then
        VALUE=$(cat "$FILE")
        sysctl -w "$KEY=$VALUE"
    else
        echo "missing backup: $FILE" >&2
        return 1
    fi
}

restore_sysctl net.core.default_qdisc "$BACKUP/default_qdisc"
restore_sysctl net.ipv4.tcp_congestion_control "$BACKUP/tcp_congestion_control"
restore_sysctl net.core.somaxconn "$BACKUP/somaxconn"
restore_sysctl net.ipv4.tcp_max_syn_backlog "$BACKUP/tcp_max_syn_backlog"
restore_sysctl fs.file-max "$BACKUP/fs.file-max"
restore_sysctl net.ipv4.ip_local_port_range "$BACKUP/ip_local_port_range"

然后删除本次新建的 sysctl 文件:

rm -f /etc/sysctl.d/98-a5idc-bbr-canary.conf
rm -f /etc/sysctl.d/99-a5idc-concurrency-canary.conf

如果原配置文件中本来就存在同名参数,不能只删除候选文件后认为已经完成回滚,应根据备份目录中的原文件恢复,并重新核对加载顺序。对于 systemd 服务覆盖文件,如果本次新建且此前不存在,可以删除:

rm -f /etc/systemd/system/nginx.service.d/limits.conf
systemctl daemon-reload
systemctl show nginx -p LimitNOFILE

如果本次新增了模块持久化文件,也可以移除:

rm -f /etc/modules-load.d/tcp-bbr.conf

不建议在仍有连接使用 BBR 时执行 modprobe -r tcp_bbr。模块保持加载并不等于新连接继续使用 BBR;只要运行时默认算法已经恢复,后续连接就会按恢复后的值创建。是否卸载模块可以留到维护窗口或下一次重启处理。

观察窗口与变更收口

BBR 切换后,至少观察一段包含真实新建连接的业务周期;短连接业务建议覆盖一个完整高峰,长连接业务则要等新旧连接同时存在的阶段结束。监听队列和文件描述符调整后,建议继续观察至少一个完整业务高峰;如果业务有明显日周期,应延长到覆盖主要高峰,必要时持续观察 24 小时。

观察窗口与变更收口配图

只有在应用错误率、连接超时、p95 延迟、TCP 重传、监听丢弃、文件句柄、内存和 CPU 软中断都处于可接受范围内,才将候选配置纳入正式变更记录。任何一个关键指标在观察窗口内持续恶化,都应以已保存的基线和回滚脚本恢复,而不是继续叠加 tcp_rmem、tcp_wmem、TIME_WAIT 或网卡队列等参数。

最终的回滚触发条件应写入变更单:当新连接失败、业务错误率持续超过基线、延迟明显恶化、监听队列开始丢弃,或系统资源接近上限时,立即停止扩容式调参并执行回滚;如果只是单项指标轻微波动,则先暂停后续步骤,延长观察并与变更前同时间段数据对比。这样才能把 BBR 和高并发参数调整控制在可验证、可撤销的生产变更范围内。