功能概述
本文介绍 TencentOS Server 4 中网络内核参数的调优方法,涵盖 TCP 核心参数、连接追踪(conntrack)、缓冲区管理、中断与多队列优化和拥塞控制选择,帮助用户在高并发网关、跨地域传输和容器网络场景下获得更稳定的网络性能。
背景信息
网络内核调优是指在高并发 Web 服务、API 网关、跨地域数据同步等场景下,针对 TCP 协议栈、连接追踪和中断处理的系统性参数调整。典型场景下的常见问题包括:
端口耗尽:短连接大量产生 TIME_WAIT 状态,导致源端口耗尽、新建连接失败。
连接追踪表打满:conntrack 表条目达到上限后,新建连接被拒绝。
吞吐量受限:默认 TCP 缓冲区不适用于高带宽、长延迟(BDP 大)链路,窗口无法填满。
带宽利用率低:公网链路丢包使 cubic 拥塞控制频繁降窗,无法充分利用带宽。
TencentOS Server 4 内置 Linux 6.6 LTS 内核,默认支持
bbr 拥塞控制算法、百万级 conntrack、TCP Fast Open 等特性。通过合理调整参数,可以让同一台 CVM 承载更多并发连接、更充分利用公网带宽。注意事项
tcp_tw_reuse NAT 冲突风险:
tcp_tw_reuse=1 在 NAT 环境下可能导致五元组冲突,即客户端经过 NAT 网关时源端口被复用。若腾讯云 CVM 作为客户端经 NAT 网关访问外部服务,不建议开启该参数。建议仅在服务端角色下启用。BBR 不适用内网:BBR 拥塞控制适用于公网长延迟且存在丢包的链路场景。在内网短延迟链路场景下,例如 CVM 之间或容器网络,BBR 的性能可能不如默认的
cubic 算法。若内网业务采用混合部署,建议使用 cubic 算法。nf_conntrack_buckets 只读:
net.netfilter.nf_conntrack_buckets 在运行时为只读状态,无法通过 sysctl 修改。需通过内核启动参数 nf_conntrack.hashsize=<N> 进行设置,修改后重启生效。参数渐进调整:网络参数调优应在完成基准测试后逐步调整。若同时修改多个参数,将难以确定各参数对性能的具体影响。
默认值差异:部分参数默认值可能因内核小版本、内存大小不同而异,建议用
sysctl -a | grep <参数名> 核实实际默认值。持久化文件位置:持久化配置文件建议存放在
/etc/sysctl.d/ 目录下。请勿直接修改 /etc/sysctl.conf 文件,以免导致配置冲突。权限要求:所有 sysctl、ethtool、/proc/irq 写操作均需 root 权限,请您以 root 或具备 sudo 权限的用户执行。
内核模块加载:使用 BBR 前需确认 tcp_bbr 模块已加载,默认未加载时需手动执行 modprobe tcp_bbr 加载模块。
连接追踪模块加载:使用 conntrack 相关参数前需确认 nf_conntrack 模块已加载,默认未加载时需手动执行 modprobe nf_conntrack 加载模块。
网卡 RSS/RFS 支持确认:中断与多队列优化依赖网卡硬件多队列(RSS)能力,请您先用 ethtool -l <网卡名> 确认网卡支持 combined 队列调整。
基准数据:调优前建议先用 iperf3、wrk 等工具采集基准性能数据,便于对比调优效果。
持久化文件位置:建议将持久化配置文件存放在/etc/sysctl.d/目录下。请勿直接修改
/etc/sysctl.conf 文件,以免导致配置冲突。接口与参数说明
TCP 连接与超时参数
参数 | 默认值 | 推荐值(高并发) | 说明 |
net.ipv4.tcp_tw_reuse | 2 | 1 | TIME_WAIT 端口复用。取值:2=仅 loopback 接口允许复用(内核默认),1=全局启用复用(要求 tcp_timestamps 开启),0=禁用。高并发服务端推荐 1;NAT 环境客户端角色不建议开启(见注意事项) |
net.ipv4.tcp_fin_timeout | 30 | 15 | FIN-WAIT-2 超时(秒) |
net.ipv4.tcp_keepalive_time | 7200 | 600 | keepalive 探测间隔(秒) |
net.ipv4.tcp_keepalive_intvl | 75 | 30 | 探测重试间隔(秒) |
net.ipv4.tcp_keepalive_probes | 9 | 3 | 探测次数 |
net.ipv4.tcp_max_tw_buckets | 4096 | 1048576 | TIME_WAIT 最大数量(实际默认值可能因内存大小自动调整) |
net.ipv4.tcp_max_syn_backlog | 1024 | 8192 | SYN 队列长度 |
net.core.somaxconn | 128 | 65535 | listen() backlog 上限 |
说明:
内核中该参数默认值与系统内存相关,计算公式为
TCP_TIMEWAIT_LEN * TCP_TW_BUCKETS_FACTOR,简化为按内存线性估算:默认值 = (memory_size_in_pages * PAGE_SIZE / 4096) 的一个比例值。实际经验值:4GB 内存约 4096,16GB 内存约 16384,64GB 内存约 65536。如需精确值,可在目标机器上执行
sysctl net.ipv4.tcp_max_tw_buckets 查看。TCP 缓冲区参数
参数 | 推荐值(高吞吐) | 说明 |
net.core.rmem_max | 16777216 | 接收缓冲区最大值(16MB) |
net.core.wmem_max | 16777216 | 发送缓冲区最大值(16MB) |
net.ipv4.tcp_rmem | 4096 87380 16777216 | TCP 接收缓冲区(min/default/max) |
net.ipv4.tcp_wmem | 4096 65536 16777216 | TCP 发送缓冲区(min/default/max) |
net.core.netdev_max_backlog | 5000 | 网卡到内核的接收队列长度 |
连接追踪(conntrack)参数
参数 | 推荐值 | 说明 |
net.netfilter.nf_conntrack_max | 1048576 | 连接追踪表最大值 |
net.netfilter.nf_conntrack_buckets | 262144 | hash 桶数量(只读,需通过 kernel 启动参数 nf_conntrack.hashsize=<N> 设置,建议不超过 nf_conntrack_max / 4,最大值受系统内存限制) |
net.netfilter.nf_conntrack_tcp_timeout_established | 3600 | ESTABLISHED 超时(秒) |
net.netfilter.nf_conntrack_tcp_timeout_time_wait | 30 | TIME_WAIT 超时(秒) |
其他 TCP 参数
参数 | 推荐值 | 说明 |
net.ipv4.tcp_timestamps | 1 | 启用时间戳(RTT 计算) |
net.ipv4.tcp_window_scaling | 1 | 启用窗口缩放 |
net.ipv4.tcp_sack | 1 | 选择性确认 |
net.ipv4.tcp_dsack | 1 | 重复 SACK |
net.ipv4.tcp_fastopen | 3 | TCP Fast Open(客户端+服务端) |
说明:
net.ipv4.tcp_low_latency 在 Linux 4.x 后已移除,内核忽略此参数,不再列为推荐调优项。操作步骤
1. 加载 BBR 拥塞控制模块
# 加载 tcp_bbr 内核模块modprobe tcp_bbr# 确认模块已加载lsmod | grep tcp_bbr# 预期输出:tcp_bbr 20480 0(或其他非空输出,表示模块已加载)# 确认 BBR 在可用算法列表中sysctl net.ipv4.tcp_available_congestion_control# 预期输出:net.ipv4.tcp_available_congestion_control = reno cubic bbr
2. 切换拥塞控制算法为 BBR
# 查看当前算法sysctl net.ipv4.tcp_congestion_control# 预期输出:net.ipv4.tcp_congestion_control = cubic# 切换为 BBR(推荐公网高带宽场景,内网场景不建议切换)sysctl -w net.ipv4.tcp_congestion_control=bbr# 预期输出:net.ipv4.tcp_congestion_control = bbr# 验证切换成功sysctl net.ipv4.tcp_congestion_control# 预期输出:net.ipv4.tcp_congestion_control = bbr
3. 查看与调整 conntrack 表
# 确认 nf_conntrack 模块已加载(若未加载,conntrack 参数路径不存在)modprobe nf_conntrack# 查看当前连接追踪统计sysctl net.netfilter.nf_conntrack_count# 预期输出:net.netfilter.nf_conntrack_count = 12345(示例值,当前已追踪的连接数)sysctl net.netfilter.nf_conntrack_max# 预期输出:net.netfilter.nf_conntrack_max = 65536(当前最大值)# 临时调大 conntrack 表最大值(运行时生效)sysctl -w net.netfilter.nf_conntrack_max=1048576# 预期输出:net.netfilter.nf_conntrack_max = 1048576
警告
nf_conntrack_buckets 运行时只读,无法通过 sysctl 修改。如需调整 hash 桶数量,需在内核启动参数中设置:# 查看当前 buckets 值cat /sys/module/nf_conntrack/parameters/hashsize# 修改 grub 启动参数(需重启生效)grubby --update-kernel=ALL --args="nf_conntrack.hashsize=262144"# 注意:重启操作会导致业务中断,请确认无关键业务运行后再执行reboot
4. conntrack 调整后验证
# 确认 max 已更新(需 nf_conntrack 模块已加载,否则参数路径不存在)sysctl net.netfilter.nf_conntrack_max# 预期输出:net.netfilter.nf_conntrack_max = 1048576# 确认当前连接数未接近 max,避免打满sysctl net.netfilter.nf_conntrack_count# 预期输出:一个远小于 max 的数值,使用率应低于 70%# 查看 conntrack 统计(关注 insert_failed、drop,应为 0)cat /proc/net/stat/nf_conntrack# 或用 ctstat 查看汇总(ctstat 由 iproute-tc 包提供,未安装时可执行 dnf install iproute-tc)ctstat -s 1# 预期输出:insert_failed=0, drop=0(若 insert_failed 持续增长说明表仍打满)
5. 中断与多队列优化(RSS)
#通过 ip link 查看网卡真实名称ip link show# RSS(接收端缩放):查看网卡多队列配置ethtool -l <网卡名># 预期输出:显示 Channel parameters,其中 Pre-set maximums 的 Combined 为最大支持队列数,Current hardware settings 的 Combined 为当前队列数(例如 Combined: 2)# 设置队列数(需网卡支持,<队列数>根据 CPU 核数确定,一般等于核数,且不能超过 Pre-set maximums 中 Combined 的最大值)ethtool -L <网卡名> combined <队列数># 预期输出:无报错,再次 ethtool -l <网卡名> 可见 Combined queues 已更新
6. 中断亲和性绑定(IRQ Affinity)
#通过 ip link 查看网卡真实名称ip link show# 查看网卡中断分布(注意:虚拟化环境网卡中断以底层设备名标识,如 virtio0-input.0,# 用网卡名 grep 可能无输出——可先执行 ethtool -i <网卡名> 查看 driver/bus-info,再按设备名检索)grep virtio /proc/interrupts# 预期输出:多行,每行对应一个收发队列中断(如 virtio0-input.0、virtio0-output.0),# 各队列中断数应大致均匀分布# 设置中断亲和性(将 <IRQ号> 替换为实际中断号,绑定到特定 CPU 掩码;# 掩码不能超过 CPU 数量——如 2 CPU 机器最大合法掩码是 3,写 f 会报 "write error: Value too large for defined data type")echo f > /proc/irq/<IRQ号>/smp_affinity# 预期输出:无报错(f 表示绑定到 CPU 0-3,ff 表示 0-7;4 CPU 机器用 f,8 CPU 用 ff)# 验证亲和性cat /proc/irq/<IRQ号>/smp_affinity_list# 预期输出:0-3(或对应 CPU 列表)
7. RPS(接收包分发)配置
# 设置 RPS CPU 掩码(<网卡名> 替换为实际网卡,rx-0 为第一个接收队列)# ffff 为 16 位 CPU 掩码,表示绑定到 CPU 0-15;CPU 数量超过 16 时需使用更长的掩码echo ffff > /sys/class/net/<网卡名>/queues/rx-0/rps_cpus# 预期输出:无报错# 设置 RPS 流表大小echo 32768 > /proc/sys/net/core/rps_sock_flow_entries# 预期输出:无报错# 验证 RPS 配置cat /sys/class/net/<网卡名>/queues/rx-0/rps_cpus# 预期输出:ffff
8. 中断优化验证
#通过 ip link 查看网卡真实名称ip link show# 查看各队列中断分布是否均衡(虚拟化环境按底层设备名检索,如 virtio)grep virtio /proc/interrupts# 预期输出:各队列中断数大致均匀,无单核被打满# 查看 softirq 网络处理统计(每行对应一个 CPU,数值为 16 进制无前缀格式)cat /proc/net/softnet_stat# 预期输出:多行,第二列(drop,16 进制)应为 00000000,# 第三列(time_squeeze,16 进制)应较小且不持续增长
9. 持久化配置
注意:配置中的
tcp_congestion_control = bbr 依赖 tcp_bbr 模块已加载(见下方开机自动加载配置),模块未加载时该参数写入会失败或被跳过。# 写入 /etc/sysctl.d/ 持久化cat > /etc/sysctl.d/99-tos-net-tune.conf << 'EOF'net.core.somaxconn = 65535net.core.rmem_max = 16777216net.core.wmem_max = 16777216net.ipv4.tcp_congestion_control = bbrnet.ipv4.tcp_max_syn_backlog = 8192net.ipv4.tcp_max_tw_buckets = 1048576net.netfilter.nf_conntrack_max = 1048576EOF# 设置 BBR 模块开机自动加载echo "tcp_bbr" > /etc/modules-load.d/tcp_bbr.conf# 应用配置sysctl --system# 预期输出:* Applying /etc/sysctl.d/99-tos-net-tune.conf ... 并列出各参数值
10. 持久化应用后验证
# 逐项确认关键参数已持久化生效sysctl net.ipv4.tcp_congestion_control# 预期输出:net.ipv4.tcp_congestion_control = bbrsysctl net.core.somaxconn# 预期输出:net.core.somaxconn = 65535sysctl net.netfilter.nf_conntrack_max# 预期输出:net.netfilter.nf_conntrack_max = 1048576
常见问题
Q1:执行 sysctl -w 报错 cannot stat /proc/sys/...: No such file or directory
原因:对应内核模块未加载(如
nf_conntrack 未加载时 conntrack 参数路径不存在)。解决:加载对应的内核模块后重试。
# 加载对应模块modprobe nf_conntrack# 确认参数路径出现ls /proc/sys/net/netfilter/nf_conntrack_max
Q2:BBR 切换后不生效,tcp_congestion_control 仍为 cubic
原因:
tcp_bbr 模块未加载,或 tcp_available_congestion_control 列表中无 bbr。解决:手动加载 tcp_bbr 模块并确认其在可用算法列表中。
# 手动加载模块modprobe tcp_bbr# 确认 bbr 在可用列表sysctl net.ipv4.tcp_available_congestion_control# 若无 bbr,确认内核版本(TencentOS Server 4 内核 6.6 LTS 已内置 BBR 支持)uname -r
Q3:执行 ethtool -L 报错 Operation not permitted 或 Invalid argument
原因:部分环境(如部分 SR-IOV 直通模式)不支持动态修改网卡队列数。
解决:确认网卡是否支持队列调整,不支持时改用 RPS 软件分发替代硬件 RSS。
# 确认网卡是否支持队列调整ethtool -l <网卡名># 若输出 Combined queues 后无 "Maximum" 支持,说明不可调整# 改用 RPS(软件分发)替代硬件 RSS(ffff 为 16 位 CPU 掩码,表示 CPU 0-15,CPU 数量超过 16 时需使用更长的掩码)echo ffff > /sys/class/net/<网卡名>/queues/rx-0/rps_cpus
Q4:conntrack 表调整后仍频繁打满,新建连接失败
原因:
nf_conntrack_max 调大但 nf_conntrack_buckets 未同步调整,hash 桶过少导致冲突严重。解决:同步调大 nf_conntrack_buckets 的 hash 桶数量。
# 查看当前 buckets(只读)cat /sys/module/nf_conntrack/parameters/hashsize# 通过内核启动参数调整 buckets(需重启,建议值不超过 nf_conntrack_max / 4,最大值受系统内存限制)grubby --update-kernel=ALL --args="nf_conntrack.hashsize=262144"# 重启(重启将导致业务中断,请在维护窗口内执行)reboot# 重启后确认 buckets 已更新cat /sys/module/nf_conntrack/parameters/hashsize
Q5:持久化配置重启后部分参数未生效
原因:
/etc/sysctl.conf 与 /etc/sysctl.d/ 下多个文件存在同名参数,加载顺序冲突。解决:排查同名参数的重复定义,统一收敛到单一配置文件。
# 检查是否有重复定义grep -r "tcp_congestion_control" /etc/sysctl.conf /etc/sysctl.d/# 统一放在 /etc/sysctl.d/99-tos-net-tune.conf,删除其他文件中的冲突项# 确认加载顺序(99- 开头保证最后加载)sysctl --system