核心是减少Nginx磁盘IO:启用access_log缓冲(buffer=64k flush=5s)、关闭静态资源与健康检查日志、禁用proxy_temp磁盘缓存并合理配置内存缓冲、开启open_file_cache和sendfile、挂载加noatime,并用iotop/lsof排查隐蔽IO源。

核心是让Nginx尽量少碰磁盘——把“边收边写”变成“攒够再发”,把“每次读都查盘”变成“查内存缓存”,把“该记的日志”和“不该记的噪音”分开处理。关键不在堆参数,而在切断高频小IO的生成路径。
用好 access_log 缓冲,堵住最常抖动的源头
默认每请求写一次日志,高并发下就是海量小IO。必须启用内存缓冲+定时刷盘:
- buffer=64k flush=5s 是黄金组合:64KB缓冲区能聚合数百次请求,5秒兜底保证不丢太多日志
- 缓冲区别设太大(如1M),断电或崩溃时丢失日志风险陡增;也别太小(如8k),起不到聚合效果
- 静态资源(.js/.css/.png)和健康检查接口(/healthz)直接 access_log off,它们本就不该进主日志流
关掉 proxy_temp 磁盘缓存,但必须配齐内存缓冲
中等大小响应(几十MB报表、JSON导出)最容易卡在“填满内存又不够大”的灰色区,反复写临时文件引发随机IO。设 proxy_max_temp_file_size 0 可禁用这部分磁盘写入,但前提是:
- proxy_buffering on(默认开启,别关)
- proxy_buffer_size 4k(只存响应头,够用)
- proxy_buffers 8 128k(总内存缓冲1MB,覆盖常见响应)
- proxy_busy_buffers_size 256k(必须 ≥ 单块buffer且 ≤ 总buffer,否则转发卡死)
让静态文件读取彻底避开磁盘
高频小文件(图标、CSS、JS哈希文件)反复 stat() 和 read() 是隐形IO大户:
- 开 open_file_cache max=10000 inactive=60s,缓存文件句柄和元数据
- 加 open_file_cache_valid 30s 和 open_file_cache_min_uses 2,避免缓存冷数据
- 务必 sendfile on,走内核零拷贝路径;别配 directio,它绕过页缓存反而更慢
- 挂载磁盘时加 noatime,省掉每次读都更新访问时间的元数据写
排查其他隐蔽IO来源
日志和代理缓存只是常见诱因,iowait高不等于问题出在这儿:
- 用 iotop -o 锁定高IO worker 进程PID,再 lsof -p $PID 看它在写哪个文件
- 检查 error_log 是否设为 debug 级——尤其 proxy_pass 或 SSL 场景下,日志量会指数爆炸
- 确认没开 client_body_in_file_only on,否则大POST请求体直写磁盘
- fastcgi/uwsgi/scgi 有自己独立的临时文件机制,与 proxy_* 参数无关,需单独审视


















