每个活跃TCP连接在Nginx中严格对应1个文件描述符(fd),因socket在用户态即表现为fd,worker进程通过epoll/kqueue监听其I/O事件;启用upstream时可达1:2映射;10万并发需综合预留日志、后端连接及缓冲,建议单进程ulimit -n ≥ 262144,且系统级、进程级、Nginx级配置须协同生效。

每个活跃的 TCP 连接在 Nginx 中必然占用 1 个文件描述符(fd),这是硬性映射,没有例外。
为什么是 1:1?
Nginx 基于事件驱动(epoll/kqueue),所有网络 I/O 都通过 fd 管理。一次客户端连接建立后,内核为其分配一个 socket,该 socket 在用户态即表现为一个 fd。Nginx 的 worker 进程通过监听这个 fd 上的可读/可写事件来收发数据。因此:
- 1 个已建立的 TCP 连接 = 1 个 socket = 1 个 fd
- 1 个正在 accept 的新连接请求(处于 SYN_RECV 状态)不计入 fd,但会受 net.core.somaxconn 限制
- 1 个被关闭但处于 TIME_WAIT 状态的连接,仍占用 1 个 fd,直到超时释放
- 如果启用了 upstream 代理,每条客户端连接还可能额外消耗 1 个 fd(用于连接后端服务),即 1:2 映射
10 万并发需要多少 fd?
不能只算“10 万”。必须预留冗余:
- 基础连接:100,000 fd(对应 10 万并发连接)
- 日志文件、配置文件、临时文件等:+2,000~5,000 fd
- upstream 代理场景(常见):+100,000 fd(后端连接)
- 系统安全缓冲与突发流量:+10%~20%
综合建议:单进程 ulimit -n ≥ 262144,全局 fs.file-max ≥ 2097152。
关键配置需协同生效
仅调高 ulimit 不够,三个层级必须一致:
- 系统级:/etc/security/limits.conf 中设置 nginx 用户的 soft/hard nofile
- 进程级:systemd service 文件中添加 LimitNOFILE=262144(若用 systemd 启动)
- Nginx 级:worker_connections 必须 ≤ 单进程可用 fd 数,例如设为 65535,配合 4 个 worker 可支撑约 26 万连接
如何验证是否到位?
运行中检查三项是否匹配:
- lsof -p $(cat /var/run/nginx.pid) | wc -l —— 实际占用 fd 数
- cat /proc/$(cat /var/run/nginx.pid)/limits | grep "Max open files" —— 进程上限
- ss -s | grep "TCP:" —— 当前 TCP 连接总数(含 ESTAB、TIME-WAIT 等)
三者应逻辑自洽,且 lsof 统计值不应频繁逼近 limits 值,否则说明瓶颈已出现在 fd 层。











