nginx req_limit 在正则表达式位置不起作用

nginx req_limit 在正则表达式位置不起作用

我有像这样的 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”区域的限制就这么高,以至于它本质上是一个没有限制的区域。

相关内容