优化nginx静态资源i/o调度的核心是缩短数据路径、减少拷贝与等待:启用sendfile实现零拷贝,配合tcp_nopush提升网络效率;禁用gzip/etag/expires等导致sendfile失效的模块;按文件大小分层调度,避免大文件挤占page cache。

优化 Nginx 处理静态资源的 I/O 调度,关键不是堆参数,而是让数据流动路径更短、更少拷贝、更少等待。核心目标是:让热文件尽可能走内存(page cache),冷大文件绕过内存直读磁盘,同时避免内核和 Nginx 之间反复“交接”数据。
用好 sendfile 实现零拷贝传输
这是最基础也最关键的一步。sendfile 能跳过用户态,让内核直接把 page cache 中的数据送进 socket 缓冲区,省掉两次 CPU 拷贝和两次系统调用。
- 必须开启:sendfile on;
- 搭配使用:tcp_nopush on;——让 sendfile 发出的数据尽量填满 TCP 报文段,减少网络小包
- 注意冲突:一旦启用 gzip、sub_filter、etag 或 expires 等需修改响应体或头的模块,sendfile 会自动失效,回退到 read+write 模式。纯静态服务建议关掉这些:gzip off; etag off; expires off;
按文件大小分层调度 I/O 方式
不能一刀切。小文件靠缓存,大文件要避让缓存,否则会挤占 page cache 空间,反而拖慢整体。
- 小文件(page cache + sendfile,不启用 directio 或 aio
- 大文件(≥ 4MB):启用 directio 4m; 和 aio on;,让内核异步读盘、绕过页缓存,避免污染内存
- 配置示例(放在 location 块内):
sendfile on;
aio on;
directio 4m;
output_buffers 1 128k;
减少元数据访问开销
每次请求都要 stat() 判断文件是否存在、是否可读?高频小文件场景下,这会成为瓶颈。
- 启用文件句柄与元数据缓存:open_file_cache max=20000 inactive=30s;
再配 open_file_cache_valid 60s; 和 open_file_cache_min_uses 2; - 关闭不必要的日志:access_log off;(尤其 CDN 边缘或纯静态节点)
- 静态路径匹配用前缀或精确匹配,避免正则:
✅ location /static/ { ... }
❌ location ~* \.(js|css|png)$ { ... }
协同内核参数保障 page cache 效率
Nginx 的 sendfile 和 open_file_cache 都高度依赖内核 page cache 的健康状态。若系统频繁 swap 或疯狂回收 dentry/inode,优化就打折扣。
- vm.swappiness=1:几乎禁用 swap,把内存留给文件缓存
- vm.vfs_cache_pressure=50:降低目录项和 inode 缓存回收倾向,提升路径查找速度
- fs.file-max=2097152:配合 Nginx 的 worker_rlimit_nofile,防文件描述符耗尽
- 挂载 SSD 分区时加 noatime,discard,logbufs=8(XFS 推荐)











