在 linux 中优化 nginx 静态文件的 io 性能,核心做法是启用 sendfile 并配合 aio(异步 i/o)或 directio。通过开启 sendfile,内核可以直接将文件数据从磁盘拷贝到 socket 缓冲区,绕过用户态,显著降低 cpu 开销;对于大文件或高并发场景,进一步启用 aio 可以让 nginx 在等待 i/o 时处理其他请求,避免阻塞。

如何配置 sendfile 和 tcp_nopush 减少上下文切换
要减少网络包发送时的上下文切换,应同时开启 sendfile 和 tcp_nopush。sendfile 负责在内核空间完成文件到套接字的传输,而 tcp_nopush 确保在发送一个完整的数据包之前,不发送部分数据包,从而合并小数据包,提高网络利用率。这两者必须配合使用,因为 tcp_nopush 依赖于 sendfile 才能生效。

server {
listen 80;
server_name example.com;
location /static/ {
root /var/www/html;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
}
}
上述配置中,sendfile on 启用内核级文件传输,tcp_nopush on 优化 TCP 数据包合并,tcp_nodelay on 则禁用 Nagle 算法,确保实时性要求高的数据立即发送。这三者结合,能有效提升静态资源加载速度。
如何利用 aio 和 directio 处理大文件并发
当服务器需要处理大量大文件并发请求时,传统的同步 I/O 会成为瓶颈。此时应启用 aio 和 directio。aio 允许 Nginx 发起异步 I/O 请求,在等待磁盘读取的同时处理其他连接;directio 则强制对大于指定大小的文件使用直接 I/O,避免占用内核页缓存,防止大文件读取导致内存压力激增。

location /large-files/ {
root /data/storage;
sendfile on;
aio on;
directio 5m;
output_buffers 1 32k;
}
在此配置中,aio on 启用异步 I/O,directio 5m 表示超过 5MB 的文件使用直接 I/O。这种组合特别适合视频、镜像等大文件服务,能显著提升并发处理能力。注意,aio 仅在 Linux 2.6+ 且支持 epoll 的系统上有效。
基于 directio 阈值设置的具体问题:大文件是否真的绕过页缓存
在启用 directio 5m 后,大于 5MB 的文件确实会绕过内核页缓存,直接从磁盘读取。这意味着这些文件不会占用系统的 page cache,从而保护了缓存空间用于更小的频繁访问文件。然而,这也意味着每次请求都需要重新从磁盘读取,增加了磁盘 I/O 负载。因此,该策略适用于访问频率低但体积大的文件,若文件虽小但访问极频,反而可能因缺乏缓存而变慢。











