![Nginx 速率限制 - 仅当达到上限时才会减速](https://linux22.com/image/728790/Nginx%20%E9%80%9F%E7%8E%87%E9%99%90%E5%88%B6%20-%20%E4%BB%85%E5%BD%93%E8%BE%BE%E5%88%B0%E4%B8%8A%E9%99%90%E6%97%B6%E6%89%8D%E4%BC%9A%E5%87%8F%E9%80%9F.png)
我们最近切换到了 nginx,我很高兴看到速率限制似乎这很简单。我为特定区域设置了以下限制:
limit_req_zone $binary_remote_addr zone=PHPUtilities:10m rate=60r/m;
我将该区域应用于突发 20 的位置块。一切似乎都很好,但令我惊讶的是,我很快就会遇到速度变慢的情况,服务器会在 5 秒左右的时间里拒绝响应。似乎 nginx 每分钟处理 60 个请求,并将其分为每秒 1 个请求。因此,如果我们同时加载多个脚本,nginx 会立即处理第一个请求,然后延迟其他请求。
我宁愿它表现得像“好吧,他们每分钟可以免费获得 60 个请求。只有一次如果达到 60,我们就会开始限制它们,首先是放慢接下来的 20 个请求(爆发)。之后的一切都将变得一团糟,直到它们不再请求那么多,或者降到每分钟 60 个的限制以下。”
有没有办法做到这一点?
PS. 我一开始在 Stack Overflow 上无意中问了这个问题,后来才意识到在这里问这个问题更合适。:(
答案1
我认为您想使用该nodelay
参数以及burst
:
location /login/ {
limit_req_zone $binary_remote_addr zone=PHPUtilities:10m rate=60r/m burst=20 nodelay;
proxy_pass http://my_upstream;
}
使用nodelay参数,NGINX仍然根据burst参数在队列中分配插槽并施加配置的速率限制,但不是通过间隔排队请求的转发。相反,当请求“太早”到达时,只要队列中有可用的插槽,NGINX 就会立即转发它。它将该插槽标记为“已被占用”,并且直到经过适当的时间(在我们的示例中,为 100 毫秒后)才释放它以供其他请求使用。