Nginx限流配置后,为什么超过3次请求就直接被拒绝了?
我按文档配置了Nginx的限流,设置的是每秒最多5次请求(burst设了3),但测试时发现超过3次就直接返回503了。代码检查了好几遍没问题,难道是我的配置哪里理解错了?
配置片段如下(简化版):<pre class="pure-highlightjs line-numbers"><code class="language-javascript"><code class="language-nginx">http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s;
}
server {
location /api {
limit_req zone=api_limit burst=3;
}
}</code></code></pre>
用ab工具测试时,-c1 -n5发现第4次请求就报错,日志显示请求被Rate limiting拒绝。明明burst是3应该允许突发到8次才对啊?求大神指指点点
burst的理解上。WP里面虽然不怎么碰Nginx底层,但这类限流坑我踩过不少。你的
rate=5r/s没问题,意思是平均每秒最多5个请求。但加上burst=3后,不是说能扛住8次,而是允许最多3个请求“排队”等处理。关键是默认还启用了nodelay么?没加的话,默认是会延迟处理 burst 的请求。但你看现象第4个就503,说明根本没有排队,直接拒了。原因在这:
limit_req zone=api_limit burst=3;这句其实等价于burst=3 nodelay吗?不是!它默认没有 nodelay,所以 Nginx 要求请求必须严格按速率来,超出 rate 的部分最多容忍 burst 个,但前提是你得让它们排队——而 ab 测试是并发打的,瞬间4个进来,1个符合速率,3个进队列,可队列要等时间片释放才能处理,ab 不等啊,超时或者服务直接503。真正想实现“突发允许到8”(即 rate=5 + burst=3),你得明确加上
nodelay:这样 Nginx 会把这3个 burst 请求立刻放行,相当于短时间能扛住最多8次(5+3)。否则,不加
nodelay,burst 是用来做平滑限流的,比如每秒放一个进去,那测试工具一并发,当然第4个就跪了。建议你加上
nodelay再用 ab -c1 -n5 测一次,应该就能看到预期效果了。不过注意,开了nodelay可能会被突增流量打爆后端,生产环境要看情况权衡。nodelay参数,加上它应该能用。默认情况下,Nginx 会尝试平滑处理突发请求,而不是直接放行,所以你需要这样配置:测试时注意清理缓存或者用不同 IP 模拟请求,不然结果可能不准。