【问题标题】:Nginx rules for upper/lower case locations大小写位置的 Nginx 规则
【发布时间】:2016-10-01 01:06:04
【问题描述】:

所以,这是我的情况。我有一个站点,其中包含一些来自单独的上游应用程序的自定义逻辑。我现在可以正常工作,没有问题,尽管我的直接解决方案有点冗长。我将很快添加更多这些自定义位置,并添加以大写和小写形式访问这些位置的功能。我的解决方案会奏效,但位置列表很快就会变得笨拙,我想重新考虑我的解决方案。

所以,假设我的上游被称为“myupstream”并且已经在文件中定义。我的自定义位置将是一、二、三和四。 (为了保护自己,实际地点名称已更改)。

所以这些网址:

http://mysite/one http://mysite/two http://mysite/three http://mysite/four

在我的 nginx.conf 中:

    location /one {
            log_request_speed_filter on;
            log_request_speed_filter_timeout 1000;
            proxy_pass   http://myupstream/one;
            proxy_set_header Host $http_host;
    }
    location /two {
            log_request_speed_filter on;
            log_request_speed_filter_timeout 1000;
            proxy_pass   http://myupstream/two;
            proxy_set_header Host $http_host;
    }
…
etc.

除了位置名称之外,所有位置都相同。

现在,地点的数量是几个,但可能会增长到几十个。然后,添加以大写和小写形式访问位置的功能。所以:

http://mysite/one http://mysite/ONE http://mysite/two http://mysite/TWO 等等……

如果我有 20 个位置,使用我当前的策略,我将在我的 nginx.conf 中创建 40 个不同的位置块。所以,我一直在寻找一种更有活力的方式。比如:

    location /(one|two|three) {
            log_request_speed_filter on;
            log_request_speed_filter_timeout 1000;
            proxy_pass   http://myupstream/$1;
            proxy_set_header Host $http_host;
    }

当然,我希望它仅适用于特定条目,因此广泛开放的规则不起作用。另外,我也想检测大写,但是在调用上游时它需要是小写。例如:

    location /ONE {
            log_request_speed_filter on;
            log_request_speed_filter_timeout 1000;
            proxy_pass   http://myupstream/one;
            proxy_set_header Host $http_host;
    }

所以问题1:

在 nginx 中有没有更好的方法来做到这一点?怎么样?

问题 2:

哪种方式资源/流程效率更高?

提前谢谢你..

【问题讨论】:

    标签: nginx nginx-location


    【解决方案1】:

    使用不区分大小写的location匹配:

    location ~* /(one|two|three) {
      log_request_speed_filter on;
      log_request_speed_filter_timeout 1000;
      proxy_pass   http://myupstream/$1;
      proxy_set_header Host $http_host;
    }
    

    还有另一种方法 - 使用模板:

    /etc/nginx/host.tmpl

    log_request_speed_filter on;
    log_request_speed_filter_timeout 1000;
    proxy_pass   http://myupstream/$host_loc;
    proxy_set_header Host $http_host;
    

    /etc/nginx/vhost.d/somehost.conf

    location /one {
      set $host_loc "one";
      include host.impl;
    }
    

    注意,Nginx 不支持位置 URI 中的变量。

    我建议您对不同的配置进行基准测试,以选择最有效的配置。

    编辑

    如果您想将/FOUR 请求传递给http://myupstream/four 以及 /FoUr 请求 http://myupstream/four 等,那么你应该使用 Perl module 这样的模块,因为 Nginx 目前没有用于小写版本 URI 的内置变量,也没有将位置 URI 转换为小写的内置函数。

    /etc/nginx/nginx.conf

    http {
      perl_set $uri_lc 'sub { return lc shift->uri; }';
    }
    

    在子程序中,我们:

    • 使用shift获取request object
    • 从请求对象中获取当前URI:shift->uri
    • 将 URI 传递给 lc function 并返回结果

    结果赋值给$uri_lcNginx变量。

    /etc/nginx/vhost.d/somehost.conf

    location ~* ^/(one|two|three)$ {
      log_request_speed_filter on;
      log_request_speed_filter_timeout 1000;
      proxy_pass   http://myupstream$uri_lc;
      proxy_set_header Host $http_host;
    }
    

    标记^(start) 和$(end) 很重要。

    【讨论】:

    • 在上面的例子中,如果有人调用example.com/FOUR,传递给上游的值是“四”还是“四”?我需要它是“四”。
    • 谢谢!这正是我所需要的。
    猜你喜欢
    • 2016-05-30
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多