【问题标题】:nginx x-accel block conflictnginx x-accel 块冲突
【发布时间】:2015-02-23 09:04:44
【问题描述】:

X-Accel-Redirect 似乎不尊重 nginx 块配置规则和先例。 考虑这个例子:

server {
   ...
   limit_conn limitedIP 10;

   location ^~ /files/ {
      internal
      alias /var/www/files/;
      limit_conn limitedIP 20;
   }

   location ~ \.php$ {
      ...
      limit_conn limitedIP 30;
   }
}

如果我直接访问 /files(同时删除内部课程),则使用 limit_conn 20 规则,这是正常的。

但是如果我在 php 脚本中使用 X-Accel-Redirect 到 /files,则会使用 limit_conn 30 规则。即使我从 php 位置块中删除该行,也会使用服务器块中的 limit_conn 10 规则,这很奇怪。最后,如果我从服务器块中删除 limit_conn 10,则使用 limit_conn 20 规则,这是我一开始所期待的。

我在 nginx 版本 1.6.2 上对此进行了测试。

limit_conn 只是一个例子,几个指令的行为是这样的。有什么想法吗?

【问题讨论】:

    标签: php nginx x-accel-redirect


    【解决方案1】:

    这就是 limit_conn 和 limit_req 模块的工作方式。这些模块处理用户和服务器之间的连接,并且由于内部重定向不会打开任何新的此类连接,Nginx 只检查每个请求的限制,并且认为没有必要再次检查它们。

    在您的示例中,用户的请求首先匹配第二个位置,这会触发第一次调用 limit_conn 处理程序。这就是使用limit_conn 30 规则的原因。处理程序将在内部重定向后第二次被调用,但它几乎会立即结束其工作而不检查任何内容 (return NGX_DECLINED)。

    如果您在第二个位置注释limit_conn 30 规则,limit_conn 10 规则将从服务器上下文继承,这对于Nginx 来说是完全正常的行为。在这种情况下,limit_conn 处理程序将首先为主请求调用,而下一次调用(在内部重定向之后)将什么也不做。

    最后,当您注释除limit_conn 20 规则之外的所有limit_conn 行时,将首先在内部重定向之后调用limit_conn 处理程序,因此最终将使用此规则。

    更新:

    由于在建立新连接时会检查 limit_conn 规则,因此打开新连接将解决您的问题。从概念上讲,配置如下所示:

    limit_conn_zone $binary_remote_addr zone=limitedIP:10m;
    
    server {
        # You can use any random unused non-system port
        listen 127.0.0.1:8889;
        server_name internal.server;
    
        set_real_ip_from  127.0.0.1/32;
        real_ip_header    X-Forwarded-For;
    
        location ^~ /files/ {
            limit_conn limitedIP 20;
            alias /var/www/files/;
        }
    }
    
    server {
        ...
    
        location ^~ /files/ {
            internal;
            proxy_set_header Host "internal.server";
            proxy_set_header X-Forwarded-For $remote_addr;
    
            # Make sure you specify the same port as above
            proxy_pass http://127.0.0.1:8889;
        }
    
        location ~ \.php$ {
            ...
            limit_conn limitedIP 30;
        }
    }
    

    但是,这种方法会导致性能明显下降,尤其是当您的文件很大时。因此,我不建议使用此解决方法。

    不幸的是,我想不出任何其他方法来解决仅使用 Nginx 的问题。

    【讨论】:

    • 所以没有办法为 X-Accel-Redirect 文件和其余 php 文件定义不同的 limit_conn 吗?
    • 从源代码来看(参见上面的提交链接),没有直接的方法可以做到这一点,除非你准备好打开一个新的连接,这会降低性能。我在原始答案中添加了一个示例。
    猜你喜欢
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    相关资源
    最近更新 更多