$request_uri 部分有不同的 limit_req

$request_uri 部分有不同的 limit_req

我想为 php-fpm 配置不同的速率限制。

我想要:

  1. 静态文件没有限制,
  2. PHP 请求有限制,
  3. PHP 请求有/ admin /.+不同的限制。

我对实现点3有问题。现在我测试:

limit_req_zone $binary_remote_addr zone=php:10m rate=2r/s;
limit_req_zone $binary_remote_addr zone=admin:10m rate=9r/s;

server {
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    limit_req_status 429;
# limitng works, server return 404
    location ~ /admin/ {limit_req zone=admin...}

    location ~ [^/]\.php(/|$) {
        limit_req zone=php burst=9 delay=4;
#limit_req not allowed here
        if($request_uri ~ /admin) {limit_req zone=admin...}
#not update limits (lower)
        location ~ ^/admin/ {limit_req zone=admin...}
#negative matching returns index.php content
        location location ~ ^/(?!(admin)) {limit_req zone=php...}
    }
}

也是limit_req_zone $request_uri,但是如果我理解正确的话,这会为/admin/1和创建不同的池/admin/2

//更新1:

我需要针对以下请求使用不同的池 /index.php?/.*/index.php?/admin/.*

答案1

根据limit_req_zone指令文档

键值为空的请求不予考虑。

因此,只需在 PHP 处理程序位置使用两个limit_req指令,并根据情况将其中一个区域键设为空$request_uri(在这种情况下,不会应用第一个或第二个请求限制率):

map $request_uri $is_admin {
    ~^/admin/  1;
    default    0;
}
map $is_admin $php_key {
    0 $binary_remote_addr;
    # an empty value otherwise by default
}
map $is_admin $admin_key {
    1 $binary_remote_addr;
    # an empty value otherwise by default
}

limit_req_zone $php_key zone=php:10m rate=2r/s;
limit_req_zone $admin_key zone=admin:10m rate=9r/s;

server {
    ...
    location ~ [^/]\.php(/|$) {
        limit_req zone=php ...
        limit_req zone=admin ...
        ...

答案2

根据文档 limit_req 仅在 http、server、location 中允许。

我建议排除 1 和 2,并使用与 / 和 admin 相同的策略来共同定位:

server {
listen 127.0.0.1:8088;
location / {
content_by_lua_block {
    ngx.say("root")
    ngx.exit(ngx.HTTP_OK)

}
}
location ~* .(jpg|jpeg|gif|png|ico|css|bmp|swf|js|html|txt)$ {
content_by_lua_block {
    ngx.say("static")
    ngx.exit(ngx.HTTP_OK)

}
}
location ~* "^\/admin($|\/(.*)$)" {
content_by_lua_block {
    ngx.say("processed by php with first ratelimit")
    ngx.exit(ngx.HTTP_OK)

}
}
location ~* "\.php$" {
content_by_lua_block {
    ngx.say("processed by php with second ratelimit")
    ngx.exit(ngx.HTTP_OK)

}
}
}

并测试:

# curl 127.0.0.1:8088/admin
processed by php with first ratelimit
# curl 127.0.0.1:8088/admin.php
processed by php with second ratelimit
# curl 127.0.0.1:8088/admin/
processed by php with first ratelimit
# curl 127.0.0.1:8088/admin/test.php
processed by php with first ratelimit
# curl 127.0.0.1:8088/test/php
root

相关内容