client_body_buffer_size按每请求独立分配内存,设为512k时1000并发即占512MB,需依据P95/P99请求体大小上浮25%设定(如P95=320KB→推荐512KB),避免过小导致落盘或过大引发OOM。

这个参数直接影响每个请求的内存开销,不是全局总和,而是“每请求独立分配”。设得稍大,高并发下内存就容易撑满。
它怎么吃掉内存
client_body_buffer_size 是 per-request 分配的缓冲区。Nginx 每收到一个 POST/PUT 请求,只要带 body,就会按该值预分配一块内存(实际还会加约 25% 安全余量)。哪怕请求体只有几百字节,这块内存也照分不误。
- 设为 512k,1000 并发上传 → 至少占用 512MB 内存(不含其他开销)
- 设为 4m,单 worker 处理 500 个请求 → 仅此项就占约 2GB RAM
- 短连接高频小请求(如 JSON 提交)看似轻量,但连接数一多,buffer 总量迅速累积
为什么不能只看“最大上传文件”来设
业务允许上传 100MB 文件,不代表每个请求都这么大。client_max_body_size 控制上限,而 client_body_buffer_size 应匹配**绝大多数请求的实际大小**(比如 P95 值),否则:
- 设太小:频繁落盘 → 磁盘 I/O 上升、延迟增加、缓存失效(proxy_cache 不缓存落盘请求)
- 设太大:大量空闲 buffer 占用内存 → worker 进程 RSS 持续攀升,可能触发 OOM
- 临界点陷阱:Nginx 内部自动扩容 25%,设 256k 可能扛不住 255KB 请求,仍写临时文件
怎么平衡才不爆内存
关键是让缓冲区“够用但不浪费”,需结合真实数据和资源约束:
- 查 access log 或前端埋点,统计 P95/P99 的 Content-Length,再上浮 25% → 得出推荐值(如 P95=320KB → 推荐 512KB)
- 纯 API(JWT+JSON):64k–128k 足够;头像/Base64 表单:256k–512k;文档直传:2m–4m
- 高并发轻量场景(如 IoT 心跳):反而可调小到 4k,换更高连接数
- 单 worker 可用内存 × 70% ÷ 预估最大并发上传数 = 该 worker 下 buffer 的安全上限
调完怎么确认没白费内存
不能只 reload 就算完,得看运行时表现:
- error.log 出现 client request body is buffered to a temporary file → 还在落盘,buffer 不够
- top/htop 观察 nginx worker 的 RSS 是否随并发线性暴涨 → 可能 buffer 设超了
- iostat -x 1 看 client_body_temp_path 所在磁盘的 %util 和 await → 明显下降说明落盘减少
- 开启 debug 日志,搜索 buffered(走内存)或 temp file(落盘)关键词











