高并发下需协同压测Nginx缓存与缓冲区,重点验证缓存命中率、busy_buffers_size是否打满、临时文件是否频繁落盘,并按响应体大小分组调优buffer参数,同时确保keepalive连接下缓冲区复用与内存预留充足。

测试高并发下 Nginx 缓存与缓冲区的协同吞吐性能,核心是让缓存命中路径和缓冲区流转路径同时承压,并验证二者是否相互拖累或错配。不能只测“开了缓存后 QPS 变高”,而要观察:缓存是否真被高频复用、缓冲区是否因响应体大小/节奏频繁落盘或阻塞、内存是否被无效缓冲占用、长尾延迟是否来自 buffer 等待。
用真实缓存请求压测,禁用本地系统缓存干扰
确保压测流量走的是 Nginx 的 proxy_cache 或 fastcgi_cache 路径,而非内核 page cache 或浏览器缓存:
- 客户端用 wrk 发起带固定 Host 和 URI 的请求(如 wrk -t8 -c2000 -d120s -H "Host: api.example.com" http://nginx-ip/v1/user/123),避免 URL 带随机参数导致缓存失效
- 在 Nginx 配置中显式关闭 sendfile 和 tcp_nopush:sendfile off; tcp_nopush off;,防止内核零拷贝绕过 buffer 控制逻辑
- 压测前清空系统页缓存:echo 3 > /proc/sys/vm/drop_caches,排除 OS 层干扰
分层观测缓存效率与缓冲区行为
单看 QPS 没意义,必须同步比对三组指标:
- 缓存有效性:通过 proxy_cache_status 自定义日志字段(如 log_format main '$remote_addr - $upstream_cache_status ...')统计 HIT/MISS/BYPASS 比例;高压下 HIT 率低于 95% 说明缓存键设计不合理或 max_size 不足
- 缓冲区压力:启用 proxy_buffering on 后,监控 proxy_busy_buffers_size 是否频繁打满(可用 nginx -T | grep buffer 确认实际值);若 wrk 输出中 P95 延迟阶梯式上升且 ss -i 显示重传率升高,大概率是 busy_buffers_size 过小导致上游等待
- 内存落地痕迹:检查 proxy_max_temp_file_size 是否触发落盘——压测中执行 lsof -p $(pgrep nginx) | grep tmp,若有大量临时文件,说明缓冲区总容量(proxy_buffers × buffer_size)不足以容纳典型响应,需调大或改用 stream 模式直通
对比不同响应体规模下的缓冲适配性
缓存内容大小直接影响缓冲区是否成为瓶颈,必须按业务典型尺寸分组测试:
- 小响应(≤2KB,如 JSON API):设 proxy_buffer_size 4k; proxy_buffers 4 4k;,重点看 P50 是否稳定在 1ms 内;若 P99 显著拉高,检查 large_client_header_buffers 是否被恶意 header 触发放大
- 中响应(200KB–2MB,如 HTML+内联资源):用 proxy_buffers 8 256k; proxy_busy_buffers_size 512k;,配合 proxy_buffering on;此时需确认 proxy_cache_use_stale updating 是否启用,避免缓存更新时缓冲区被锁死
- 大响应(>5MB,如下载包):直接关缓冲 proxy_buffering off 并启用 proxy_http_version 1.1; proxy_set_header Connection '';,让数据流式透传;否则缓冲区会吃光内存并触发 OOM killer
验证缓存与缓冲在连接复用下的协同稳定性
Keepalive 连接下,缓冲区状态会跨请求延续,容易积累异常:
- 上游配置必须含 keepalive 128;,且 Nginx 侧设 proxy_http_version 1.1; proxy_set_header Connection '';,否则每个请求新建连接,缓冲区无法复用,测不出真实协同效果
- 压测中用 ss -i state established '( dport = :80 )' | head -20 查看单连接的 retrans、rto、qsize 字段;若 qsize 持续 > 0 且 rto 缩短,说明缓冲区写入慢于网络发送,需调大 proxy_busy_buffers_size 或降低 proxy_buffers 数量防内存碎片
- 检查 worker_connections 是否足够支撑长连接数 × 缓冲区内存:例如 1000 个 keepalive 连接 × 每个连接平均占用 1MB 缓冲,需预留 1GB 内存,远超默认配置











