高并发服务器在上线前,最容易被忽视的往往是 Linux 内核参数调优。很多服务明明代码没有瓶颈,却因为文件描述符耗尽、TIME_WAIT 堆积、TCP 全连接队列过小而频繁出现 5xx 与连接超时。sysctl 调优能在不改一行业务代码的情况下,把单机连接能力提升数倍,是每个后端与运维工程师必须掌握的基础功。
一、为什么必须做内核参数调优
Linux 的默认内核参数面向”通用低负载”场景设计,单进程默认只能打开 1024 个文件描述符,TCP 的本地端口范围也偏保守。当 Nginx、Redis、MySQL 或自研网关在一台 2C4G 甚至更高配置的机器上扛万级并发时,这些默认值立刻成为天花板。一次真实排障中,我们正是用 Linux 性能排查实战 的套路定位到 “too many open files”,根源就是没调内核参数。
二、文件描述符与进程限制
第一步不是改内核,而是放开”用户态”限制。编辑 /etc/security/limits.conf,为运行服务的用户提高 nofile 上限:
# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
# 若服务用 systemd 托管,还需在 unit 文件加:
# [Service]
# LimitNOFILE=65535
修改后重登会话,用 ulimit -n 验证是否生效;systemd 服务则需 systemctl restart 让 LimitNOFILE 真正生效。
三、TCP 网络栈调优
高并发网关最关键的几项,集中在 /etc/sysctl.conf 或 /etc/sysctl.d/99-tuning.conf:
# /etc/sysctl.d/99-tuning.conf
# 1. 扩大本地端口范围,缓解客户端短连接耗尽
net.ipv4.ip_local_port_range = 1024 65535
# 2. 快速复用 TIME_WAIT 端口,避免端口占满
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
# 3. 提升全连接队列,防 SYN 丢包
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# 4. 扩大文件句柄与收发缓冲
fs.file-max = 1000000
net.core.netdev_max_backlog = 65535
核心参数与作用的对应关系如下:
| 参数 | 默认值 | 推荐值 | 作用 |
|---|---|---|---|
| tcp_tw_reuse | 0 | 1 | 复用 TIME_WAIT 端口,缓解短连接耗尽 |
| somaxconn | 128 | 65535 | 提高 accept 队列,防高并发丢连接 |
| ip_local_port_range | 32768-60999 | 1024-65535 | 扩大可用客户端端口 |
| fs.file-max | 视内存 | 1000000 | 系统级最大打开文件数 |
四、虚拟内存与 swap 策略
数据库与缓存对 swap 很敏感。Redis 官方建议把 vm.overcommit_memory 设为 1,避免 fork 时因内存申请被拒而失败;同时把 vm.swappiness 调低,减少被动换页带来的毛刺:
vm.swappiness = 10
vm.overcommit_memory = 1
vm.overcommit_ratio = 90
# Docker 场景下还需注意 vm.max_map_count(ES 依赖)
vm.max_map_count = 262144
这些参数配合 Nginx 反向代理 的 worker_connections 调大,才能把单机吞吐真正释放出来。
五、一键应用与验证
写入配置后,用下面命令加载并自检:
sysctl --system # 加载 /etc/sysctl.d 下所有配置
sysctl net.ipv4.tcp_tw_reuse # 确认单项已生效
ss -s # 查看 socket 统计,关注 TIME-WAIT 数量
cat /proc/sys/fs/file-nr # 已分配/上限,确认 file-max 生效
六、调优后如何量化效果
调参不是终点。建议接上 Prometheus + Grafana 监控,观察 TCP 重传率、ESTABLISHED 连接数与文件描述符使用率的变化曲线;再用压测对比调优前后的 QPS 与 P99 延迟,用数据证明这次 Linux 内核参数调优确实生效。记住:所有参数都应先在预发环境验证,再灰度到生产,避免 net.ipv4.tcp_tw_recycle 这类已被废弃的参数带来连接异常。




