nginx limit_req不起作用

时间:2015-02-09 16:14:49

标签: nginx webserver rewrite rate

我正在尝试用nginx(v1.6.2)

实现一个简单的速率限制系统

sites-available / 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;
    }
}

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;
}

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

速率限制/运行正常。如果我对此页面的请求过多,我会收到错误503 问题:/email/subscribe/api/api/test都不受费率限制,我不知道原因。它必须与rewrite做一些事情,但问题是什么? 有任何想法吗?我尝试了一切!

请注意:我已更改了文件名和网址端点。

1 个答案:

答案 0 :(得分:4)

问题是几个phases重写阶段的nginx进程请求在 preaccess 之前进行(这是应用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;
    }
}

如果你选择第二个选项,你的配置会更干净,但有点hacky。我们将使用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;
    }
}