要让大报文请求尽量不落盘、减少IO,核心是合理设置client_body_buffer_size以覆盖P95/P99请求体并避开25%安全扩容触发点,同时兼顾内存开销与后端承接能力。

要让大报文请求尽量不落盘、减少 IO,核心是让 client_body_buffer_size 覆盖绝大多数真实请求体大小,并避开 Nginx 内部的“25% 余量触发机制”,同时控制内存总开销不超标。
看准真实请求体分布,别只盯平均值
光查平均上传大小没用,得统计 P95 或 P99 的 Content-Length。比如日志里 95% 的 POST 请求体在 320KB 以内,那就不能简单设成 320k——Nginx 实际尝试分配时会加 25%(即 320k → 400k),若刚好卡在边界,仍可能写临时文件。稳妥做法是上探到 512k 或干脆 1m。
- 纯 JSON + JWT 头:64k~128k 足够
- 含小图 Base64 的表单:建议 ≥128k,256k 更稳
- 文档/压缩包类上传(≤20MB):可设 2m~4m,但必须同步确认后端能接住
避开缓冲区临界点,防止“差一点就落盘”
Nginx 不是严格按配置值切分内存和磁盘,它内部会做一次“安全扩容”:
- 若请求已知长度(有
Content-Length),且该长度 ≤client_body_buffer_size × 1.25,则用实际长度分配缓冲区 - 否则,直接按配置值分配;超出部分一律写入
client_body_temp_path - 举例:设为 256k,实测最大请求体是 255KB,因 255 × 1.25 ≈ 319k > 256k,仍可能触发落盘;设成 384k 或 512k 才更可靠
控内存总量,防高并发下被拖垮
每个连接都会独占一份缓冲区内存。设成 1m,在 3000 并发时就额外吃掉 3GB RAM。不是越大越好,得算账:
- 轻量 API(高频 JSON):保持默认 8k 或调小到 4k,省内存保连接数
- 中低频大报文(如后台上传接口):可设 512k~2m,配合限流或独立 location 隔离
- 务必禁用
client_body_in_file_only on,避免误开强制落盘
验证是否真走内存,别信配置信日志
改完配置后,必须验证运行态行为:
- 开启 debug 日志:
error_log /var/log/nginx/debug.log debug;,搜索"client request body buffered"或"in memory" - 压测时用
iostat -x 1观察client_body_temp_path所在磁盘的write/s是否明显下降 - 检查临时目录下文件创建频次(如用
inotifywait监控CREATE事件),归零才算到位

















