Nginx Worker 复用文件描述符需协同配置 open_file_cache 四项参数:max、inactive、valid、min_uses,并启用 errors 和 events,配合 worker_rlimit_nofile、sendfile 及日志优化。

要让 Nginx Worker 进程真正复用文件描述符(fd),减少非阻塞读取小文件时的磁盘打开损耗,关键不是简单开启缓存,而是让 open_file_cache 与 Worker 的 I/O 行为协同工作。它不缓存文件内容,只缓存 fd、大小、修改时间、存在性等元数据,目标是跳过重复的 open()、stat() 系统调用——这些调用在高频静态资源访问中才是真正的瓶颈。
必须配齐的四项基础参数
单独写 open_file_cache on; 完全无效。以下四项需统一放在 http 或 server 块中,缺一不可:
-
容量与淘汰策略:
open_file_cache max=5000 inactive=60s;——最多缓存 5000 个条目;60 秒内未被访问则标记为可淘汰 -
元数据校验周期:
open_file_cache_valid 30s;——每 30 秒主动stat()一次,检查文件是否仍存在、mtime 是否变化、权限是否有效 -
准入门槛防污染:
open_file_cache_min_uses 2;——同一文件在inactive时间窗口内至少被请求 2 次才进入缓存,避免低频或临时路径占位 -
错误结果也缓存:
open_file_cache_errors on;——把 404(文件不存在)、403(权限不足)等失败状态也记入缓存,防止恶意扫描反复触发磁盘查询
让 Worker 真正复用 fd 的关键细节
缓存了 fd 不代表一定能复用。Worker 进程能否跳过重新打开,取决于底层机制是否就绪:
- 启用
open_file_cache_events on;(推荐),依赖内核 inotify 实时感知文件变更;若内核低于 2.6.27 或禁用 inotify,可关闭此项,靠valid轮询兜底 - 确保
worker_rlimit_nofile设置足够大(如65535),否则即使缓存了 fd,进程级句柄上限也会卡住复用 - 搭配
sendfile on;使用,让内核直接传输文件内容,避免用户态拷贝;这与 fd 复用形成性能组合,尤其适合小文件
按业务节奏调优参数值
参数不是固定模板,要匹配你的静态资源访问特征:
- 如果资源更新频繁(如前端构建后哈希文件批量上线),
inactive可设为 20–30s,valid控制在 10–20s,避免返回已删除文件的 200 响应 - 若资源总数超万(如大型 SPA 项目),
max可提至 10000–50000;每个缓存条目约占用 1KB 内存,注意别吃光可用内存 - 日志中频繁出现
could not build optimal open_file_cache,大概率是系统 inotify 限制低了,需调大/proc/sys/fs/inotify/max_user_watches
配合其他优化压降整体 IO 开销
单开 open_file_cache 是起点,再叠加几项配置能进一步释放 Worker 的非阻塞 I/O 效能:
- 在纯静态资源配置块中(如
location ~ \.(js|css|png|woff2)$),关闭访问日志:access_log off; log_not_found off;,省掉磁盘写入开销 - 对明确不变更的路径(如
/healthz、/index.html),可在对应location块里单独启用缓存,避免影响动态接口 - 优先使用前缀匹配(
location /static/)而非正则匹配静态路径,减少运行时路径解析开销

















