nginx limit_req 不起作用

Flo*_*der 4 webserver rewrite nginx rate

我正在尝试使用 nginx (v1.6.2) 实现一个简单的速率限制系统

网站可用/mysite.com

limit_req_zone $binary_remote_addr zone=myzone:10m rate=2r/m;

server {
    listen                      80;
    server_name                 mysite.com;
    root                        /var/www/vhosts/mysite.com;
    error_log                   [..];
    access_log                  [..];

    include                     conf.d/php-fpm.conf;

    location = / {
        limit_req               zone=myzone burst=3 nodelay;
        index                   index.html;
    }

    location / {
        try_files               $uri =404;
    }

    location ^~ /pages {
        include                 conf.d/php-fpm.conf;
        internal;
    }

    location = /email {
        rewrite ^(.*)$          /pages/email.html;
    }

    location = /email/subscribe {
        limit_req               zone=myzone burst=2 nodelay;
        rewrite ^(.*)$          /pages/email.php?action=subscribe;
    }

    location ~ /api {
       limit_req                zone=myzone burst=5 nodelay;
       rewrite ^(.*)$           /pages/api.php;
    }
}
Run Code Online (Sandbox Code Playgroud)

conf.d/php-fpm.conf

location ~ \.php$ {
    if (!-f $document_root$fastcgi_script_name) {
        return 404;
    }
    fastcgi_pass                unix:/var/run/php5-fpm.sock;
    fastcgi_index               index.php;
    fastcgi_param               SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_split_path_info     ^(.+?\.php)(/.*)$;
    fastcgi_param               PATH_INFO $fastcgi_path_info;
    include                     fastcgi_params;
}
Run Code Online (Sandbox Code Playgroud)

nginx.conf:没什么有趣的,只有
include sites-enabled/*;

速率限制/工作正常。如果对此页面的请求过多,我会收到错误 503。
问题:既没有/email/subscribe/api也没有/api/test速率限制,我不知道为什么。它必须与 做些什么rewrite,但有什么问题呢?
有任何想法吗?我什么都试过了!

请注意:我更改了文件名和 URL 端点。

Ale*_*Ten 6

问题是 nginx 在几个阶段处理请求,重写阶段在预访问之前(这limit_req是应用的地方)。因此,在您的配置请求有/pages/...机会受到限制之前,它们会被重写。为了避免这种情况,您应该在重写(使用break标志)或使用try_files.

我更喜欢第一个选项,因此您的配置可能如下所示:

limit_req_zone $binary_remote_addr zone=myzone:10m rate=2r/m;

server {
    listen                      80;
    server_name                 mysite.com;
    root                        /var/www/vhosts/mysite.com;
    error_log                   [..];
    access_log                  [..];

    include                     conf.d/php-fpm.conf;

    location = / {
        limit_req               zone=myzone burst=3 nodelay;
        index                   index.html;
    }

    location / {
        try_files               $uri =404;
    }

    location ^~ /pages {
        include                 conf.d/php-fpm.conf;
        internal;
    }

    location = /email {
        rewrite ^(.*)$          /pages/email.html;
    }

    location = /email/subscribe {
        limit_req               zone=myzone burst=2 nodelay;
        rewrite ^(.*)$          /pages/email.php?action=subscribe break;
        fastcgi_pass            unix:/var/run/php5-fpm.sock;
        fastcgi_param           SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include                 fastcgi_params;
    }

    location ~ /api {
       limit_req                zone=myzone burst=5 nodelay;
       rewrite ^(.*)$           /pages/api.php break;
       fastcgi_pass             unix:/var/run/php5-fpm.sock;
       fastcgi_param            SCRIPT_FILENAME $document_root$fastcgi_script_name;
       include                  fastcgi_params;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你选择第二个选项,你的配置会更干净一点,但有点麻烦。我们将使用try_files阶段在limit_req阶段之后运行的事实,这try_files使得内部重定向到它的最后一个参数。

limit_req_zone $binary_remote_addr zone=myzone:10m rate=2r/m;

server {
    listen                      80;
    server_name                 mysite.com;
    root                        /var/www/vhosts/mysite.com;
    error_log                   [..];
    access_log                  [..];

    include                     conf.d/php-fpm.conf;

    location = / {
        limit_req               zone=myzone burst=3 nodelay;
        index                   index.html;
    }

    location / {
        try_files               $uri =404;
    }

    location ^~ /pages {
        include                 conf.d/php-fpm.conf;
        internal;
    }

    location = /email {
        rewrite ^(.*)$          /pages/email.html;
    }

    location = /email/subscribe {
        limit_req               zone=myzone burst=2 nodelay;
        try_files SOME_NONEXISTENT_FILE /pages/email.php?action=subscribe;
    }

    location ~ /api {
       limit_req                zone=myzone burst=5 nodelay;
       try_files SOME_NONEXISTENT_FILE /pages/api.php;
    }
}
Run Code Online (Sandbox Code Playgroud)