nginx通过root/alias直读静态文件并启用sendfile,可高效利用linux内核page cache;需配合open_file_cache缓存元数据,禁用aio和atime更新,并避免proxy_pass等代理行为以确保零拷贝路径。

Nginx 本身不直接控制操作系统内核的页缓存(Page Cache),但它能高效利用 Linux 的 OS 缓存机制——只要静态文件由 Nginx 直接提供(即 root/alias 方式服务,而非 proxy_pass),文件内容就会自然落入内核的 page cache 中,后续请求可零拷贝读取,显著降低 I/O 延迟。
关键在于:让 Nginx 尽量绕过用户态缓冲,直通内核缓存。以下是具体做法和注意事项:
一、确保静态资源走文件系统直读(非代理)
只有 location 中使用 root 或 alias,且未启用 proxy_pass、fastcgi_pass 等上游转发时,Nginx 才会调用 open() + sendfile()(或 read() + write())读取本地文件,从而触发 OS 缓存。
✅ 正确示例:
location /static/ {
alias /var/www/static/;
# 无 proxy_pass,Nginx 直接读磁盘 → 文件进 page cache
}
❌ 错误示例(绕过 OS 缓存):
location /static/ {
proxy_pass http://backend; # 即使 backend 是本机,也走 socket,不进 page cache
}
二、启用 sendfile 并配合相关优化
sendfile 是 Linux 零拷贝系统调用,它让内核直接从文件 page cache 发送到 socket buffer,完全避免用户态内存拷贝。
在 http 或 server 块中开启:
sendfile on; tcp_nopush on; # 配合 sendfile,合并 TCP 包提升吞吐 tcp_nodelay on; # 对小响应(如 HTML)减少延迟,与 sendfile 不冲突
⚠️ 注意:
sendfile在某些场景下会失效(如启用了gzip、sub_filter、X-Accel-Redirect),此时 Nginx 回退到read()+write(),仍能受益于 page cache,但多一次内存拷贝。
三、调优 open_file_cache 提升元数据访问效率
OS 缓存的是文件内容(page cache),而 open_file_cache 缓存的是文件元数据(inode、权限、打开状态等),二者协同工作:
open_file_cache max=10000 inactive=30s; open_file_cache_valid 60s; open_file_cache_min_uses 2; open_file_cache_errors on;
-
max=10000:最多缓存 10,000 个打开文件句柄 -
inactive=30s:30 秒内未被访问的条目被清理 -
min_uses=2:同一文件被至少访问 2 次才进入缓存 → 过滤冷文件
这能大幅减少 stat()、open() 系统调用开销,尤其对大量小文件(如图标、字体)效果明显。
四、避免干扰 OS 缓存的行为
以下配置会削弱或绕过 page cache 效果:
-
启用
aio threads或aio on(Linux 5.0+):异步 I/O 可能绕过 page cache(取决于内核实现),一般静态资源无需开启,反而增加复杂度。 -
频繁
touch或cp更新文件:会改变 inode 或 mtime,导致 page cache 失效;推荐用原子重命名(mv new.js old.js)更新,保持 inode 不变更利于缓存复用。 -
挂载文件系统时加
noatime,nodiratime:禁用访问时间更新,减少写入,间接保护 page cache 稳定性(建议在/etc/fstab中配置)。
五、验证是否命中 OS 缓存
可通过以下方式确认:
-
首次请求后查看 page cache 占用:
# 请求一个静态文件,如 curl -I /js/app.js grep -i "cached" /proc/meminfo # 看 Cached 和 SReclaimable 值是否上升
-
对比两次请求的磁盘 I/O:
iostat -x 1 # 观察 %util 和 r/s;第二次请求时 r/s 应显著下降
-
用
pcstat工具检查单个文件是否在缓存中:pcstat /var/www/static/app.js # 显示 cached: true/false
不复杂但容易忽略。











