Nginx的location规则:优先级和路径替换

Nginx是反向代理和负载均衡的首选工具,nginx的location配置有许多细节内容在网上不容易找到资料,或者解释不清。本文对locaiton的常见特性进行介绍。

 

location的优先级

locaiton有四种类型的匹配规则,分别为

  • 完全匹配(=)
  • 无正则普通匹配(^~)^ 表示“非”,~ 表示“正则”,字符意思是:不要继续匹配正则
  • 正则表达式匹配(~或者~*)
  • 普通匹配

规则

  • 等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项
  • 剩下的几种匹配优先级略复杂,具体可以参考Nginx文档(http://nginx.org/en/docs/http/ngx_http_core_module.html#location
    • ^~和普通匹配。使用前缀匹配,不支持正则表达式,如果有多个location匹配成功的话,不会终止匹配过程,会记忆表达式最长的那个
    • 如果上一步得到的最长的location为^~类型,则表示阻断正则表达式,不再匹配正则表达式
    • 如果上一步得到的最长的location不是^~类型,继续匹配正则表达式,只要有一个正则成功,则使用这个正则的location,立即返回结果,并结束解析过程

“最长”命中

^~和普通命中,都是优先使用匹配最长的结果,示例如下:

location ^~ /a {
    root /;
}
location ^~ /aaa {
    root /aaa;
}

如果url为/aaa,则上面两个location都匹配成功,但用于location ^~ /aaa较长,所以最终会以/aaa作为root

上例中如果是普通匹配(把location的^~去掉),结果也是一样的

 

示例

location /test_1 {
    return 400;
}
location ^~ /test {
    return 401;
}

如上如果path为/test_1,返回的是400,说明^~优先级并不比普通匹配高

 

location /test_1 {
    return 400;
}
location ^~ /test {
    return 401;
}
location ~ /test {
    return 402;
}

如上如果path为/test_1,返回的是402,此时^~和普通匹配只记住了最长一个location /test_1,会阻止正则

如果path为/test,返回401,此时^~和普通匹配只记住了最长一个location ^~ /test,会阻止正则

 

 

路径替换

规则

配置proxy_pass时,可以实现URL路径的部分替换。

proxy_pass的目标地址,默认不带/,表示只代理域名,url和querystring部分不会变(把请求的path拼接到proxy_pass目标域名之后作为代理的URL)

如果在目标地址后增加/,则表示把path中location匹配成功的部分剪切掉之后再拼接到proxy_pass目标地址

比如请求 /a/b.html

location /a {
    proxy_pass http://server;
}
location /a {
    proxy_pass http://server/;
}

如上两个匹配成功后,实际代理的目标url分别是

http://server/a/b.html (把/a/b.html拼接到http://server之后)

http://server/b.html (把/a/b.html的/a去掉之后,拼接到http://server/之后)

要求

注意的是,对于location为正则表达式的匹配,proxy_pass的目标地址不可以带/

比如,如下配置会报错:

location ~ /abc(.*) {
    proxy_pass   http://127.0.0.1/x;
}

正则表达式的替换

如果是正则表达式,想要实现proxy_pass的路径替换,可以使用如下方式:

location ~ /abc(.*) { # 注意,使用这种方式,location内部不能包含if语句,否则proxy_pass不会生效
    proxy_pass   http://127.0.0.1/x$1;
}

如上可以把(.*)所匹配的内容拼接到http://127.0.0.1/abc之后,关于$1的使用,可以参考各种编程语言的正则表达式

另一种方法是:

location  /abc { # 这里也可以是正则
    proxy_pass http://127.0.0.1/x$request_uri;
}

 

没有更多推荐了,返回首页