在高并发大流量业务场景下(如反向代理、网关或核心后端服务集群),新部署的 Linux 操作系统默认内核配置通常偏向保守,这主要是为了兼顾桌面客户端与低配置服务器。一旦 QPS 突破上万,系统经常出现 Connection reset by peer、Too many open files 或大批连接停留在 TIME_WAIT 状态等典型瓶颈。
本文汇总了我们在生产环境中经过数百台高负载节点验证的内核网络与系统级调优清单。
1. 突破文件描述符限制 (File Descriptors)
在 Linux 体系中,“一切皆文件”,每一个 TCP Socket 连接在操作系统层面都对应一个文件描述符(fd)。Linux 默认的进程最大打开文件数通常是 1024,在高并发场景下瞬时连接数会迅速将其打爆。
修改 /etc/security/limits.conf,追加如下全局配置:
# 修改系统全局软硬限制
* soft nofile 1048576
* hard nofile 1048576
* soft nproc 1048576
* hard nproc 1048576
root soft nofile 1048576
root hard nofile 1048576
同时确保 systemd 服务管理器没有单进程覆盖限制,在 /etc/systemd/system.conf 中设置:
DefaultLimitNOFILE=1048576
DefaultLimitNPROC=1048576
2. TCP 握手队列深度调优
客户端在发起连接时,服务端存在两个核心队列:
- 半连接队列 (SYN Queue): 存放收到客户端 SYN 包、等待客户端回复三次握手 ACK 的连接。
- 全连接队列 (Accept Queue): 已经完成三次握手、等待应用程序调用
accept()读取的连接。
在高并发突发流量下,全连接队列极易占满,导致后续握手直接被丢弃。我们需要增大相关系统参数:
# sysctl.conf 配置调优
# 全连接队列最大长度 (默认 128)
net.core.somaxconn = 65535
# 半连接 SYN 队列最大长度
net.ipv4.tcp_max_syn_backlog = 65535
# 网卡驱动接收队列最大长度
net.core.netdev_max_backlog = 32768
3. TIME_WAIT 状态快速回收与复用
当作为反向代理(如 Nginx、Caddy)或微服务互相高频 RPC 短连接调用时,主动关闭连接方会产生数以万计的 TIME_WAIT 状态,占用大量内存与本地临时端口(Ephemeral Ports)。
注意:在 Linux 4.12+ 内核中,tcp_tw_recycle已经彻底被废弃并移除,因为它在经过 NAT 网关时会导致握手时间戳校验错乱。我们应当使用tcp_tw_reuse。
# 允许将处于 TIME_WAIT 状态的套接字重新用于新的 TCP 连接 (仅对客户端/出向连接有效)
net.ipv4.tcp_tw_reuse = 1
# 允许的最大 TIME_WAIT 套接字数量
net.ipv4.tcp_max_tw_buckets = 50000
# 扩大对外连接可用的本地端口范围 (默认通常为 32768 - 60999)
net.ipv4.ip_local_port_range = 10240 65535
# 缩短保持存活的探测间隔
net.ipv4.tcp_fin_timeout = 15
4. TCP 读写缓冲区动态分配
TCP 的吞吐量受限于滑动窗口和拥塞控制。针对千兆/万兆网卡,应适度调大收发缓冲区上限:
# 读缓冲区 min default max
net.ipv4.tcp_rmem = 4096 87380 16777216
# 写缓冲区 min default max
net.ipv4.tcp_wmem = 4096 65536 16777216
# 开启 TCP 窗口缩放 (RFC 1323)
net.ipv4.tcp_window_scaling = 1
# 启用现代 BBR 拥塞控制算法 (需要内核版本 >= 4.9)
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
5. 配置持久化与验证生效
将上述参数写入 /etc/sysctl.d/99-custom-tuning.conf,并执行如下指令使配置立即生效:
# 加载并生效内核配置
sudo sysctl -p /etc/sysctl.d/99-custom-tuning.conf
# 验证当前使用的拥塞控制算法
sysctl net.ipv4.tcp_congestion_control
# 输出应为:net.ipv4.tcp_congestion_control = bbr
本文作者:Alex Chen
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Alex's Devlog!