关键是要隔离磁盘、分散目录、控制生命周期:用独立ssd挂载点配置client_body_temp_path,设两级子目录、noatime;合理调buffer和超时参数;严格管控权限、定时清理、磁盘监控;后端需流式读取以缩短临时文件驻留时间。

关键不是“加个路径就行”,而是让上传临时文件不抢系统盘、不卡住事件循环。核心动作是隔离磁盘、分散目录、控制生命周期。
给 client_body_temp_path 配独立 SSD 挂载点
别用默认路径(如 /var/cache/nginx/client_body_temp),它常和系统日志、根分区共用一块磁盘。高并发上传时,大量小文件写入会拖慢整个磁盘队列,连带影响响应速度甚至 worker 进程调度。
- 准备一块空闲 SSD(或低负载 NVMe 分区),单独挂载,例如:
mount /dev/nvme0n1p1 /data/nginx/upload-temp - 在 nginx.conf 的 http 或 server 块里显式配置:
client_body_temp_path /data/nginx/upload-temp 1 2;
其中 1 2 表示两级子目录(最多 256×256 = 65536 个目录),避免单目录下文件过多导致 inode 查找变慢 - 挂载时加上 noatime:防止每次读写都更新访问时间戳,减少元数据 I/O
配合 buffer 和超时参数,减少落盘频次
临时文件不是越早写越好,而是尽量让小上传全程走内存,大上传也快速进缓冲队列,不卡 worker。
- 设
client_body_buffer_size 128k;:适合含图片的表单(≤2MB),90% 请求不落盘;若纯文本或 JSON,可设 8k–16k;若支持百 MB 分片上传,反而建议调小到 4k–8k,省内存给连接数 - 必须同步设
client_max_body_size 20m;(按业务上限略放大),否则 buffer 再大也会被 413 拦截 - 加
client_body_timeout 30s;:防慢速上传长期占着缓冲区,避免内存无效占用
权限、清理与监控不能漏
Nginx 不自动清理失败上传残留的临时文件,也不检查磁盘是否快满了——这些得你兜底。
- 确保路径属主为 worker 用户(如 www-data):
chown -R www-data:www-data /data/nginx/upload-temp,权限设700 - 加定时清理(如 cron 每 10 分钟执行一次):
find /data/nginx/upload-temp -type f -mmin +30 -delete
超过 30 分钟未修改的临时文件大概率已失效 - 监控该路径所在磁盘使用率,超过 85% 就告警;同时用
iostat -x 1看对应设备的 %util 和 await,持续高于 70% 或 20ms 就要干预
和后端协同,缩短临时文件驻留时间
Nginx 只负责暂存,真正处理在后端。如果后端接收慢或没启用流式读取,临时文件就会一直挂着不删。
- 后端服务(如 Python Flask/FastAPI、Node.js)应支持分块读取请求体,收到一部分就处理一部分,别等整个文件传完才开始
- 反向代理场景下,配好
proxy_read_timeout(建议 ≥ 60s),避免 Nginx 因等待后端响应而提前删掉临时文件 - 若后端能直接从标准输入或内存流读取(如 FastCGI 的
FCGI_STDIN),就不用依赖磁盘临时文件,Nginx 可设client_body_in_file_only off;(默认值)











