Linux服务器的网络性能直接决定了高并发场景下的吞吐能力和响应延迟。内核网络参数的默认配置面向通用场景,在高流量Web服务器、数据库代理或API网关节点上往往无法发挥硬件的全部潜力。本文围绕TCP拥塞控制算法选择、连接追踪表容量、套接字缓冲区设置三个方面,给出服务器运维中可直接套用的调优方案。
TCP拥塞控制算法对比与切换
Linux内核支持多种TCP拥塞控制算法,默认使用CUBIC。CUBIC基于立方函数调节拥塞窗口,在长距离高带宽链路上恢复速度较快,但在存在丢包的网络环境中容易触发窗口缩减,导致吞吐量波动。BBR(Bottleneck Bandwidth and RTT)由Google提出,通过测量瓶颈带宽和最小RTT来控制发送速率,不依赖丢包作为拥塞信号,在长肥管道(高带宽延迟积链路)上表现更稳定。
查看当前可用算法和正在使用的算法:
# 查看可用拥塞控制算法
sysctl net.ipv4.tcp_available_congestion_control
# 输出示例: net.ipv4.tcp_available_congestion_control = reno cubic bbr
# 查看当前算法
sysctl net.ipv4.tcp_congestion_control
# 输出示例: net.ipv4.tcp_congestion_control = cubic
# 临时切换为BBR
sysctl -w net.ipv4.tcp_congestion_control=bbr
# 永久生效
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p
BBR需要内核版本4.9以上。对于Ubuntu 18.04+/CentOS 8+系统,BBR通常已编译进内核但未默认启用。切换后可以通过iperf3进行前后对比测试:
# 服务端
iperf3 -s
# 客户端测试
iperf3 -c 192.168.1.100 -t 30 -P 4
# -P 4 表示4条并行流,模拟高并发场景
连接追踪表与文件描述符限制
conntrack(连接追踪)是Netfilter防火墙的核心机制,用于记录每个网络连接的状态。高并发服务器上,conntrack表满会导致新连接被丢弃,表现为间歇性的连接超时。默认的conntrack表大小通常为65536,在高流量场景下需要调大。
# 查看当前conntrack表大小和用量
sysctl net.netfilter.nf_conntrack_max
sysctl net.netfilter.nf_conntrack_count
# 调整conntrack表大小为256万条目
sysctl -w net.netfilter.nf_conntrack_max=2621440
# 调整哈希桶大小(需在模块加载时设置)
echo 327680 > /sys/module/nf_conntrack/parameters/hashsize
# 缩短已建立连接的超时时间
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=7200
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30
文件描述符是另一个常见瓶颈。Linux默认的进程级文件描述符上限为1024,对于Nginx、HAProxy等高并发服务远远不够。需要同时调整系统级和进程级限制:
# 查看系统级上限
cat /proc/sys/fs/file-max
# 永久调整进程级限制
cat >> /etc/security/limits.conf << 'EOF'
* soft nofile 1048576
* hard nofile 1048576
EOF
# systemd服务需在service文件中设置
# /etc/systemd/system/nginx.service.d/override.conf
[Service]
LimitNOFILE=1048576
# 调整系统级上限
sysctl -w fs.file-max=2097152
sysctl -w fs.nr_open=1048576
TCP套接字缓冲区与队列参数
TCP发送和接收缓冲区的大小直接影响数据传输效率。缓冲区过小会导致窗口受限,大文件传输或高吞吐场景下频繁触发拥塞控制;缓冲区过大则浪费内存。内核支持自动调优(TCP Autotuning),但在特定场景下手动设置更可控。
# TCP接收缓冲区(最小/默认/最大,单位字节)
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
# TCP发送缓冲区
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
# 启用TCP窗口缩放
sysctl -w net.ipv4.tcp_window_scaling=1
# 启用TCP Fast Open
sysctl -w net.ipv4.tcp_fastopen=3
# 调整SYN队列和Accept队列长度
sysctl -w net.ipv4.tcp_max_syn_backlog=65535
# 调整系统级listen backlog上限
sysctl -w net.core.somaxconn=65535
TIME_WAIT状态优化与端口耗尽
高并发短连接场景下,大量连接处于TIME_WAIT状态会占用端口资源,导致"Cannot assign requested address"错误。解决思路包括加速TIME_WAIT回收、启用端口复用和增大可用端口范围。
# 启用TIME_WAIT状态套接字复用
sysctl -w net.ipv4.tcp_tw_reuse=1
# 缩短TIME_WAIT持续时间(默认60秒)
sysctl -w net.ipv4.tcp_fin_timeout=15
# 扩大本地端口范围
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
# 增大最大TIME_WAIT套接字数
sysctl -w net.ipv4.tcp_max_tw_buckets=1048576
tcp_tw_reuse=1允许将TIME_WAIT状态的端口用于新的出站连接,对入站连接无影响。该选项在NAT环境中也安全使用,不会导致连接混淆。相比之下,已移除的tcp_tw_recycle在NAT环境中会引发连接异常,不应再尝试启用。
网络中断优化与RPS/RFS配置
多核服务器上,网络中断默认由单一CPU核心处理,成为高流量场景的瓶颈。RPS(Receive Packet Steering)和RFS(Receive Flow Steering)将网络包的软中断处理分发到多个CPU核心,提升网络处理并行度。
# 设置RPS,将eth0的接收队列0映射到所有CPU核心
echo ffffffff > /sys/class/net/eth0/queues/rx-0/rps_cpus
# 启用RFS
echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
sysctl -w net.core.rps_sock_flow_cnt=327680
# 使用ethtool调整网卡多队列
ethtool -L eth0 combined 8 # 启用8个收发队列
对于万兆网卡,建议启用XPS(Transmit Packet Steering)配合RPS使用,将发送队列也绑定到特定CPU核心,减少锁竞争。完整的调优配置应写入/etc/sysctl.d/99-network-tuning.conf并执行sysctl --system使其永久生效。每次修改后通过ss -s和netstat -s监控连接状态分布,确认参数调整效果。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/linux-nei-he-wang-luo-can-shu-diao-you-tcp-yong-se-kong-zhi/