open_file_cache不直接失效fd,而是通过缓存条目状态控制复用:valid仅决定stat校验频率,条目失效由校验失败、错误缓存、信号触发或inotify事件引起,fd在expire时被close;需协同配置max、inactive、min_uses、errors及worker_rlimit_nofile。

open_file_cache 不直接“失效”文件描述符(fd),而是通过一套协同机制控制缓存条目的有效性与复用条件。真正决定 fd 是否还能被复用的,是缓存条目(ngx_open_file_cache_node_t)的状态是否有效——而这个状态由多个参数共同驱动,其中 open_file_cache_valid 只负责“检查频率”,不决定“存活时间”。
缓存条目何时被标记为失效?
一个缓存条目被标记为无效(invalid),意味着它下次被访问时将触发重新 open/stat,原有 fd 会被 close 并丢弃。触发失效的常见情况包括:
- 执行
open_file_cache_valid定期校验时,stat()失败(如文件被删、权限变更、inode 变化) - 配置了
open_file_cache_errors on;,且某次 open/stat 返回 404/403,该错误结果被缓存并标记为有效条目;后续若文件恢复,需等下一次 valid 校验才能更新状态 - 收到
SIGHUP(重载配置)或USR1(日志轮转)信号,整个缓存被强制清空 - 启用
open_file_cache_events on;时,inotify 监听到文件被修改或删除,立即置为 invalid
fd 实际关闭的时机
文件描述符不会一直保持打开。它的生命周期依附于缓存条目状态:
- 条目处于 active(正被请求引用)且未失效 → fd 保持打开,供后续请求复用
- 条目被标记为 invalid 或超时 inactive → 在下一次
ngx_open_file_cache_expire()执行时,Nginx 主动调用close(fd),然后释放内存 - worker 进程退出或重载时,所有 fd 会被内核自动回收
如何让失效管理更及时、更可控?
关键不是调高 valid 值,而是匹配业务节奏做组合配置:
- 静态资源稳定(如 hash 命名的 JS/CSS):可设
valid 60s+inactive 300s,降低校验开销 - 热更新频繁(如灰度发布目录软链切换):建议
valid 10–20s+open_file_cache_retest,加快感知变化 - 小规格服务器或冷热混杂路径多:提高
min_uses至 3,避免低频路径过早占位并长期滞留 - 必须确保
worker_rlimit_nofile足够大(如65535),否则即使缓存有效,也无法打开新 fd
注意:日志句柄完全不走这条路
open_file_cache 对 access_log 和 error_log 的文件句柄无任何影响。日志句柄由 open_log_file_cache 独立管理,或由 kill -USR1 触发轮转。混淆二者是常见配置失误。











