Linux内核网络栈参数调优原理
Linux服务器在高并发网络场景下,默认内核参数往往成为性能瓶颈。内核网络栈从网卡接收数据包到应用层处理,经过中断、软中断、协议栈、套接字缓冲区等多个环节,每个环节都有对应的调优参数。
网卡接收到数据包后触发硬件中断,内核将中断处理推迟到软中断(NAPI)中批量处理。net.core.netdev_max_backlog参数控制软中断处理队列的最大长度,当网络包到达速率超过软中断处理速率时,超出的包会被丢弃。在高吞吐场景下,默认值1000远远不够。
# /etc/sysctl.conf 网络栈核心参数
net.core.netdev_max_backlog = 10000
net.core.somaxconn = 65535
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 65536
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535
rmem_max和wmem_max分别设置套接字接收和发送缓冲区的最大值(字节)。对于高延迟网络或大流量传输,16MB的缓冲区能显著减少丢包和重传。tcp_rmem和tcp_wmem的三个值依次为最小值、默认值和最大值,内核会根据内存压力动态调整。
TCP连接建立与TIME_WAIT优化
短连接密集型服务(如HTTP/1.1、微服务RPC)最常见的瓶颈是TIME_WAIT状态连接耗尽端口资源。Linux默认的TIME_WAIT超时为60秒,在高QPS场景下短时间内会积累大量TIME_WAIT连接。
tcp_tw_reuse=1允许内核将TIME_WAIT状态的连接重新用于新的出站连接,配合ip_local_port_range扩大端口范围,能有效缓解端口耗尽问题。tcp_max_tw_buckets控制同时存在的TIME_WAIT连接上限,超过后内核直接删除最早的连接。
# 查看当前TIME_WAIT连接数
ss -ant state time-wait | wc -l
# 查看各状态连接分布
ss -ant | awk '{print $1}' | sort | uniq -c | sort -rn
对于入站连接,somaxconn参数控制listen() backlog的最大值,即全连接队列的长度。Nginx等Web服务器默认backlog为511,如果内核somaxconn小于这个值,实际取较小者。在高并发接入场景下将somaxconn提升到65535,确保连接不被内核丢弃。
中断亲和性与RSS多队列配置
多核服务器的网络中断默认由CPU 0处理,导致单核成为瓶颈。RPS(Receive Packet Steering)和RSS(Receive Side Scaling)将网络包分发到多个CPU核心处理,实现并行化。
# 查看网卡中断分配
cat /proc/interrupts | grep eth0
# 设置RPS,将eth0的rx-0队列分发到所有核心
echo ffffffff > /sys/class/net/eth0/queues/rx-0/rps_cpus
# 设置RPS流表大小
echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
对于支持多队列的网卡(如Intel X710、Mellanox ConnectX),通过ethtool配置RSS队列数,每个队列对应一个中断和独立的CPU核心处理。队列数应与物理核心数匹配,避免超线程带来的额外开销。
irqbalance守护进程默认自动分配中断亲和性,在NUMA架构下效果不理想。生产环境建议关闭irqbalance,手动编写中断亲和性脚本,确保每个中断绑定到对应NUMA节点的CPU核心。
文件描述符与内存限制调整
网络连接本质上消耗文件描述符,Linux默认的nofile限制(1024)远不能满足高并发需求。需要同时调整系统级和用户级限制。
# /etc/security/limits.conf
* soft nofile 1048576
* hard nofile 1048576
* soft nproc 65535
* hard nproc 65535
# /etc/sysctl.conf 系统级限制
fs.file-max = 2097152
fs.nr_open = 2097152
vm.swappiness = 1
vm.overcommit_memory = 1
file-max是内核级别的全局文件描述符上限,nr_open是单进程可打开的最大文件描述符数。swappiness控制内核交换倾向,设为1表示只在内存即将耗尽时使用交换分区。overcommit_memory=1允许内核过度分配内存,对Redis等依赖fork()的服务必不可少,否则BGSAVE操作会因内存不足失败。
Conntrack与防火墙性能优化
Netfilter连接跟踪表(conntrack)在高并发下容易溢出,导致新连接被丢弃。dmesg中出现nf_conntrack: table full, dropping packet即为此问题。
# 查看当前conntrack使用情况
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
# 调整conntrack表大小
net.netfilter.nf_conntrack_max = 524288
net.netfilter.nf_conntrack_tcp_timeout_established = 7200
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 30
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 30
tcp_timeout_established默认为5天(432000秒),对大多数业务过长。调整为7200秒(2小时),使空闲连接更快释放。close_wait和fin_wait的超时从默认的60秒缩减到30秒,加速连接回收。
如果服务不依赖conntrack功能(如纯路由器或NAT由上游设备处理),可以直接在iptables规则中使用NOTRACK跳过连接跟踪,性能提升可达30%以上。对于Kubernetes节点,kube-proxy的iptables模式天然依赖conntrack,此优化不适用,需考虑切换到IPVS模式。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/linux-fu-wu-qi-nei-he-can-shu-diao-you-yu-wang-luo-zhan/