直接在全链路压测中验证limit_req削峰填谷效果,关键在于观察请求速率分布、响应延迟变化及后端负载平滑度,需结合状态统计、流量打标、对比实验和下游指标闭环分析。

直接在全链路压测环境中验证 limit_req 的削峰填谷效果,关键不是“看日志有没有 503”,而是观察请求速率分布、响应延迟变化和后端负载的平滑程度。Nginx 本身不提供“削峰填谷可视化”,需要结合指标采集、请求打标和对比实验来闭环验证。
一、提前配置带状态统计的 limit_req(启用 burst + nodelay + keyzone)
单纯限速(如 limit_req zone=api burst=10)只做硬拦截,无法体现“填谷”——即把突增请求缓冲并匀速释放。必须启用 nodelay 或配合延迟策略,并暴露当前 zone 状态:
- 定义带共享内存的限流区:
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s; - 应用时允许缓冲并立即转发(削峰):
limit_req zone=api burst=200 nodelay;(注意:nodelay 表示 burst 内请求不延迟,适合测吞吐上限) - 或启用平滑释放(更贴近“填谷”):
limit_req zone=api burst=200;(无 nodelay 时,burst 超出部分会按 rate 匀速放行) - 开启状态接口(需编译含
ngx_http_limit_req_module,默认支持):location /limitz { limit_req_status on; },可返回当前 zone 的 queued/passed/rejected 数值(需搭配 OpenResty 或自研模块增强,标准 Nginx 需用 stub_status + 自定义 log_format 提取)
二、压测中区分“原始流量”和“限流后流量”特征
全链路压测流量通常带唯一 trace_id 或压测标识(如 header X-Scene: stress)。建议在 Nginx 中打标,便于后端/监控分离分析:
- 在限流前用
map标记是否进入 burst 队列:map $limit_req_status $req_queued { "delayed" 1; default 0; } - 记录到 access_log:
log_format limitlog '$time_iso8601 $status $limit_req_status $upstream_response_time $req_queued'; - 这样就能从日志中统计:多少请求被延迟(queued=1)、平均排队时长、延迟后是否成功抵达后端、后端响应时间是否更稳定
三、核心观测维度(不依赖 Nginx 自身图表)
真正反映“削峰填谷”的是下游指标的变化趋势,而非 Nginx 单点数据:
- 上游请求速率曲线:对比压测工具(如 JMeter/GoReplay)发出的原始 RPS 和 Nginx access_log 中实际 forward 的 RPS(过滤 status 2xx),看峰值是否被压平、谷值是否被抬高
- 后端服务负载:观察应用 CPU、GC 频率、线程池 busy rate。若限流生效,“填谷”会使后端负载曲线更平稳,避免毛刺式飙升
- 端到端 P95 延迟:未限流时,高峰常伴随延迟陡增;启用 burst+delay 后,P95 应呈缓升缓降,且整体方差缩小
-
rejected vs delayed 分布:通过
$limit_req_status(值为 passed/delayed/rejected)统计比例。理想填谷效果是 rejected≈0,delayed 占比 10%~30%,且 delayed 请求的 upstream_response_time 分布集中(说明匀速释放)
四、做一次有对照组的压测实验
不要只跑一遍。至少设计两组:
- 对照组:关闭 limit_req(注释或设极高速率),跑相同压测模型,记录原始峰谷形态
-
实验组:启用
limit_req zone=api burst=150 rate=80r/s(根据后端容量设定),复现相同流量模式 - 用 Grafana 对齐时间轴,叠加绘制:上游 RPS、后端 QPS、平均延迟、错误率。削峰填谷有效的标志是——实验组的后端 QPS 曲线更接近直线,而上游 RPS 峰值下降、拖尾延长
不复杂但容易忽略:limit_req 的“填谷”本质是用时间换空间,它不减少总请求数,只是重排时序。所以一定要看下游系统反应,而不是只盯着 Nginx 拒绝了多少请求。


















