反向代理下每个客户端连接至少占用2个文件描述符(FD),分别用于客户端与Nginx、Nginx与上游服务器的socket连接;还需额外预留FD给日志、SSL缓存、临时文件等,推荐worker_rlimit_nofile设为worker_connections的1.25倍以上,并启用upstream keepalive以复用连接降低FD峰值。

反向代理模式下,每个客户端连接会占用两个文件描述符(fd):一个用于客户端到 Nginx 的连接,另一个用于 Nginx 到上游服务器的连接。这不是 bug,而是 TCP 连接模型的自然结果——Nginx 作为中间人,必须同时维持两端 socket。若忽略这点,按单连接估算 fd 需求,极易触发 “Too many open files” 错误。
理解双 fd 消耗的本质
在纯 Web 服务(非反代)场景中,一个 client 连接只对应一个 socket(client ↔ Nginx),fd 消耗是 1:1。但反向代理下,Nginx 必须主动发起上游连接(client ↔ Nginx ↔ upstream),因此每个活跃请求至少持两个 socket 句柄。此外,还可能额外占用 fd 于:日志文件、临时磁盘缓冲(如 client_body_in_file_only 开启时)、SSL 会话缓存文件、共享内存段等。
- 典型高并发反代场景中,实际 fd 消耗 ≈ 客户端连接数 × 2 + 固定开销(日志、缓存等)
- 若启用 keepalive 到 upstream,上游连接可复用,能显著降低后端 fd 峰值,但 client 端连接仍独立计数
- HTTP/2 或 gRPC over HTTP/2 场景下,单个连接可承载多路请求,但 socket 本身仍占 1 个 fd;此时更需关注 buffer 和 stream 管理,而非单纯 fd 数量
配置时预留足够余量
worker_rlimit_nofile 设置值不能仅对标 worker_connections,而应按反代特性放大估算。推荐按以下比例设定:
- worker_connections 设为 worker_rlimit_nofile 的 70%~80%,即留出 20%~30% 给日志、上游连接、临时文件等
- 例如:设 worker_rlimit_nofile 65535,则 worker_connections 不宜超过 52428(≈65535×0.8)
- 若预期峰值并发连接为 30,000,按双 fd 估算需至少 60,000 fd,再加 20% 余量 → 建议 worker_rlimit_nofile ≥ 72,000
验证与监控关键点
仅靠配置不等于生效,必须验证真实 fd 使用情况:
- 查当前 worker 进程软限制:
cat /proc/$(pgrep nginx | head -1)/limits | grep "Max open files",确认 soft limit 达到预期值 - 实时观察 fd 占用:
lsof -p $(pgrep nginx | head -1) | wc -l或ss -s中的 “total” 与 “tcp” 行对比 - 检查错误日志是否仍有
accept() failed (24: Too many open files)或connect() failed (24: Too many open files)—— 后者明确指向 upstream 连接失败,是双 fd 压力的直接信号
配合 upstream keepalive 减少波动
启用 upstream keepalive 能复用后端连接,避免每次请求都新建 socket,从而平抑 fd 波动:
- 在 upstream 块中添加:
keepalive 32;(保持最多 32 个空闲连接) - 在 proxy_pass 对应 location 中启用:
proxy_http_version 1.1;<br>proxy_set_header Connection '';
- 注意:keepalive 连接本身也占用 fd,但生命周期长、复用率高,整体比短连更节省资源










