nginx的open_file_cache通过缓存文件元信息和已打开文件描述符,减少open()/stat()系统调用,提升静态资源服务性能;需配置max、inactive、valid、min_uses等参数,并配合open_file_cache_events与长cache-control策略协同优化。

在高并发 Web 服务中,频繁打开和关闭文件会带来显著的系统开销。Nginx 的 open_file_cache 指令正是为缓解这一问题而设计——它通过缓存文件元信息(如 inode、修改时间、权限)和已打开的文件句柄,减少 open()、stat() 等系统调用,从而提升静态资源响应速度与整体吞吐量。
open_file_cache 的核心作用机制
该指令并不缓存文件内容,而是缓存对文件的“访问能力”:包括文件是否存在、是否可读、最后修改时间,以及在满足条件时复用已打开的文件描述符(fd)。当后续请求命中缓存条目且文件未变更,Nginx 可直接使用缓存中的 fd 进行 sendfile() 或读取,跳过系统调用开销。
- 缓存条目包含:文件路径哈希、inode、size、mtime、access time、fd(若启用
open_file_cache_events且内核支持) - 仅对
location中启用try_files、alias、root且实际触发文件读取的请求生效 - 不缓存动态内容(如 PHP-FPM 响应)、不缓存非 GET/HEAD 请求的文件访问
关键配置参数与合理取值
启用需配合多个子指令协同工作,单独设置 open_file_cache 不生效:
-
open_file_cache max=10000 inactive=60s;:最多缓存 10000 个条目,60 秒内未被访问则标记为非活跃 -
open_file_cache_valid 60s;:每 60 秒检查一次缓存中文件的 mtime 是否变化(通过stat()),决定是否刷新元信息 -
open_file_cache_min_uses 2;:某文件在inactive时间窗口内至少被访问 2 次才保留进缓存(避免临时热文件污染) -
open_file_cache_errors on;:缓存文件不存在或无权限等错误状态,避免重复系统调用判断
典型生产配置示例:
open_file_cache_valid 30s;
open_file_cache_min_uses 3;
open_file_cache_errors on;
文件句柄重用的前提与限制
真正复用 fd 需满足严格条件:
- 必须启用
open_file_cache_events on;(默认 off),且运行在支持 inotify 的 Linux 内核上 - 文件不能被其他进程截断(truncate)或替换(如原子更新:rm + write + rename);否则 inode 变更,fd 失效
- Nginx 主进程无法共享 fd 给 worker 进程,因此每个 worker 拥有独立的 fd 缓存池
- 缓存中 fd 仅用于
sendfile场景;若需读取后处理(如添加 header、gzip),仍会走用户态 read,此时 fd 复用价值降低
验证与调优建议
可通过日志与系统指标确认效果:
- 开启
error_log /path/to/log notice;,观察是否有open() "/xxx" failed (24: Too many open files)减少 - 用
lsof -p $(cat /var/run/nginx.pid) | wc -l对比启用前后 worker 进程打开的文件数变化 - 监控
nginx_stub_status中Reading和Writing状态连接数,结合响应延迟判断 I/O 压力是否下降 - 避免过度增大
max值:超出系统fs.file-max或单进程ulimit -n会导致启动失败或 fd 耗尽
不复杂但容易忽略:缓存效果高度依赖静态资源稳定性与访问模式,上线前应在压测中观察 cache hit rate 与系统调用次数变化。











