我有像这样的 nginx 文件部分
http {
limit_req_zone $binary_remote_addr zone=limit:1m rate=10r/s;
server {
listen 443 ssl;
server_name domain.temp;
root "/var/www";
index index.php;
location ~* ^/([0-9]+)$ {
rewrite ^/([0-9]+)$ /blank.php?id=$1 last;
limit_req zone=limit burst=3;
}
location /apply/ {
limit_req zone=limit burst=6;
}
}
}
}
确实/apply/
正常工作,但受到 6 次爆发的限制,其余的则很慢
但^/([0-9]+)$
不起作用并且没有任何效果
但如果我移动limit_req zone=limit burst=3;
到块中server{}
,它会对块内的所有内容起作用,但我希望它只在^/([0-9]+)$
块上起作用
答案1
这可能与rewrite ^/([0-9]+)$ /blank.php?id=$1 last;
指令有关。nginx 文档状态:
last
停止处理当前的 ngx_http_rewrite_module 指令集并开始搜索与改变的 URI 匹配的新位置;
可能是在 nginx 中rewrite
之前已经处理过limit_req
,因此 nginx 开始处理/blank.php
,并且由于没有location
与该请求匹配的块,所以没有分配限制。
如果这是限制不起作用的原因,那么绕过它就有些复杂了。location
块仅匹配没有查询参数的 URL 路径。因此,您需要:
location /blank.php {
limit_reqzone=limit burst=3;
# PHP processing directives from "location ~ \.php$" block
}
但是,这会匹配所有请求blank.php
。如果要限制匹配仅包含id
查询参数的请求,则需要更复杂的设置:
http {
# If there is "id" argument in query arguments and it is a number, use "limit" zone. By default, use "nolimit" zone.
map $arg_id $limit_zone {
~ ^[0-9]+$ limit;
default nolimit;
}
limit_req_zone $binary_remote_addr zone=limit:1m rate=10r/s;
limit_req_zone $binary_remote_addr zone=nolimit:1m rate=1000r/s;
server {
location /blank.php {
limit_req zone=$limit_zone burst=6;
# PHP processing directives from "location ~ \.php$" block
}
location /apply {
limit_req zone=limit burst=6;
}
}
我没有看到直接映射速率受限/非速率受限请求的直接方法。
因此我们需要用它map
来选择一个限制区域,“nolimit”区域的限制就这么高,以至于它本质上是一个没有限制的区域。