真正有效的验证必须分层观察:连接级看ss -i窗口值是否匹配tcp_rmem,传输级查/proc/net/snmp重传率

测试不同缓冲区大小对 Nginx 吞吐量的影响,不能靠简单压测看 QPS 就下结论。真正有效的验证必须分层观察:连接级窗口是否撑开、传输级是否减少重传、应用级请求体是否全程走内存。否则你调大了 client_body_buffer_size,但日志里还是频繁出现“buffered to a temporary file”,那吞吐提升就是假象。
看连接级 TCP 窗口是否匹配配置
缓冲区调优本质是让内核 TCP 接收窗口(RWIN)能覆盖带宽时延积(BDP)。光改 net.ipv4.tcp_rmem 不够,得确认它真生效:
- 用
ss -i -t -n dst :80查活跃连接,重点看rcv_wscale(窗口缩放因子)和rcv_ssthresh(接收窗口上限),数值应接近你设的tcp_rmem中间值(比如设为4096 262144 8388608,就该看到约 256KB) - 对比不同缓冲配置下
ss -i输出的rcv_rtt和rcv_space:RTT 稳定且接收空间持续饱满,说明窗口没被填满或收缩,缓冲设置偏小
查传输级重传率与分段效率
吞吐瓶颈常藏在丢包和重传里,缓冲太小会导致频繁小包发送、触发快速重传:
- 压测前后分别运行:
cat /proc/net/snmp | grep Tcp: | awk '{print $2, $12}',提取TcpInSeg(入向段数)和TcpRetransSeg(重传段数) - 重传率 =
TcpRetransSeg / TcpInSeg,低于 0.1% 才算缓冲未成为瓶颈;若从 0.8% 降到 0.05%,说明调大缓冲后滑动窗口更稳定 - 再看
/proc/net/snmp中TcpInSeg与TcpOutSeg比值:调优前若远大于 1(如 3.2),说明大量小包;调优后趋近于 1(如 1.05),表示分段更合理、吞吐潜力释放
验应用级请求体是否驻留内存
针对 client_body_buffer_size 类参数,必须确认上传行为真实路径,而非只信配置值:
- 开启 debug 日志:
error_log /var/log/nginx/debug.log debug_http;,然后发一个略超当前 buffer 的 POST 请求(如 buffer=8k,发 12KB body) - 搜索日志:
grep "http client request body" /var/log/nginx/debug.log,出现buffered表示成功驻留内存;若见buffered to a temporary file,说明已落盘,当前 buffer 失效 - 辅助验证:
lsof -p $(pgrep nginx) | grep -c "tmp",结果 > 0 说明 worker 进程打开了临时文件句柄,buffer 设置不足或client_max_body_size限制过早拦截(需确保后者 ≥ 前者)
跑跨地域真实场景压测
本地回环(127.0.0.1)压测会掩盖缓冲问题,因为 RTT≈0,BDP≈0,再小的 buffer 也够用:
- 在高延迟环境部署客户端:例如北京服务器 + 新加坡 wrk 客户端(RTT≈80ms,带宽 1Gbps),BDP ≈ 10MB,此时
tcp_rmem中间值至少设到 4MB~8MB 才可能见效 - 命令示例:
wrk -t4 -c200 -d30s --latency http://nginx-ip/upload,重点关注Requests/sec和Latency Distribution 95% - 同步在服务端运行:
iftop -P 80或nethogs -p,确认网卡出向实际利用率 ≥ 90%,排除带宽、磁盘 I/O 或 CPU 成为新瓶颈











