使用nginx代理限制每个用户的后端资源使用情况

时间:2015-01-31 05:58:53

标签: ruby-on-rails nginx proxy unicorn

我正在使用nginx代理一个运行Ruby on Rails应用程序的独角兽上游。我希望能够限制单个用户(IP地址)可以消耗的后端资源总量。通过后端资源,我的意思是用户可以同时在上游独角兽进程上运行的活动请求数。

因此,例如,如果IP地址已经有2个写入连接到特定上游,我希望任何进一步的请求由nginx排队,直到之前打开的连接之一完成。请注意,我不希望删除请求 - 它们应该等到用户的写入连接数低于2。

这样,我可以确保即使一个用户尝试了很多非常耗时的操作请求,他们也不会消耗所有可用的上游独角兽工作者,并且一些独角兽工作者仍然可以为其他用户提供服务。 / p>

似乎ngx_http_limit_conn_module可能会这样做,但文档不够明确,我无法确定。

另一种思考问题的方法是,我希望通过使服务器看起来像任何一个IP地址来防止DoS(但不是DDoS,即我一次只关心来自一个IP的DoS)能够处理N个同时发出的请求。但实际上服务器可以处理10 * N个请求,但是我将来自任何一个IP的同时请求限制为服务器实际容量的十分之一。就像普通服务器的行为一样,当超过同时工作者的数量时,请求会排队,直到之前的请求完成为止。

2 个答案:

答案 0 :(得分:2)

您可以使用limit_req模块 http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

它不限制连接数,但它限制了每秒的请求数。只需使用大突发来延迟请求而不是丢弃它们。

这里的例子。

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=2r/s;
    ...
    server {
        ...
        location / {
            limit_req zone=one burst=50;
        }

你知道平均请求处理时间是1秒,所以设置限制为2r / s只允许两个工作人员忙于这个特定的IP地址(当然,大约是)。如果请求需要0.5秒才能完成,您可以设置4r / s。

答案 1 :(得分:0)

如果您知道耗时的网址,那么您可以使用limit_req模块为长请求实现2r / s,对短请求没有限制。

http {
    ...
    #
    # Limit request processing rate or connection
    # If IP address is 127.0.0.1, the limit_conn_zone will not count it.
    #
    geo $custom_remote_addr $custom_limit_ip {
        default     $binary_remote_addr;
        127.0.0.1   "";
    }
    limit_req_zone $custom_limit_ip zone=perip:10m rate=2r/s;
    ...
    server {
        ...
        # By default, do not enforce the maximum allowed number of connections for the remote IP
        set $custom_remote_addr 127.0.0.1;

        # If the URI matches a super time consuming requests, limit to 2r/s.
        if ($uri ~* "^/super-long-requests") {
            set $custom_remote_addr $remote_addr;
        }
        limit_req zone=perip burst=50;
        ...
    }
 }