nginx高并发下文件描述符耗尽本质是系统、用户、进程三层限制未同步对齐,需同步调优fs.file-max、limits.conf、systemd limitnofile及worker_rlimit_nofile,并关闭冗余keepalive、启用tcp_tw_reuse等优化释放fd。

高并发下 Nginx 文件描述符(fd)耗尽,本质是连接数突破了系统和进程级的资源上限,直接表现为 accept() failed (24: Too many open files) 错误,新连接被静默丢弃。这不是配置“没开大”,而是需要从内核、系统用户限制、Nginx 进程三者协同收紧与扩容。
同步提升系统级文件描述符上限
每个 TCP 连接、打开的静态文件、日志句柄都占用一个 fd。默认系统全局限制(fs.file-max)和单进程限制(nofile)通常只有几千,远低于万级并发需求。
- 临时扩大全局上限:
sysctl -w fs.file-max=1000000 - 永久生效:在
/etc/sysctl.conf中添加fs.file-max = 1000000 - 为 nginx 用户设硬/软限制:编辑
/etc/security/limits.conf,加入nginx soft nofile 65535nginx hard nofile 65535 - 若用 systemd 启动,还需在
/etc/systemd/system/nginx.service.d/override.conf中配置:[Service]LimitNOFILE=65535
对齐 Nginx 进程自身资源限制
仅调系统限制不够——Nginx 必须主动声明它“能用多少”。否则即使系统允许,worker 进程仍按默认 ulimit 运行。
- 在 main 块中设置:
worker_rlimit_nofile 65535;(该值应 ≥worker_connections× worker 数) - 确保
worker_connections值合理:例如 4 核机器配worker_processes auto;+worker_connections 10240;,理论并发约 4×10240 = 40960,此时worker_rlimit_nofile至少设为 65535 才够余量 - 重启前验证:
ulimit -n在 nginx 启动用户下执行,应返回 65535;也可用cat /proc/$(pgrep nginx)/limits | grep "Max open files"查看实际生效值
减少无效 fd 占用,加快连接生命周期退出
高频短连接场景下,大量空闲 keepalive 连接长期持有 fd,比建连慢更致命——它们不干活却卡着槽位。
- 禁用长连接:
keepalive_timeout 0;(写在 http 或 server 块),响应后立即断开,释放 fd 最快 - 启用主动清理:
reset_timedout_connection on;,对超时握手、读写失败连接直接发 RST,不等内核默认 2MSL 超时 - 避免冗余配置:
keepalive_requests在 timeout=0 时失效,删掉可防误解 - 配合内核参数:
net.ipv4.tcp_tw_reuse = 1允许 TIME_WAIT socket 重用于新连接(需net.ipv4.tcp_timestamps = 1支持)
验证与持续观察
优化不是一劳永逸。上线后必须监控真实 fd 使用水位,而非只看理论值。
- 实时查看当前使用量:
lsof -u nginx | wc -l或cat /proc/$(pgrep nginx)/fd | wc -l - 检查 TIME_WAIT 连接数:
netstat -ant | grep TIME_WAIT | wc -l - Nginx 自带状态页(需启用 stub_status)可看 active connections,结合 worker 数反推 fd 压力
- 错误日志中持续出现
Too many open files,说明仍有某环未对齐,优先复查 limits.conf 和 systemd override 是否加载成功











