前言
近幾年Nginx在企業(yè)上的應用很廣泛,但很多朋友還是不知道Nginx的location優(yōu)先級,如果不能清晰的掌握nginx的location優(yōu)先級,就會在配置Nginx的時候引起錯誤的跳轉,錯誤的跳轉往往就是一次嚴重的線上事故。因此,掌握Nginx的location優(yōu)先級非常重要。
先來一個最簡單的nginx配置
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
location / {
return 400;
}
}
}
location /是通配的,也就是所以請求都能匹配,但它的優(yōu)先級我們暫時還不知道。請求結果如下:
多個通配的優(yōu)先級測試,加入location /test
location / {
return 400;
}
location /test {
return 401;
}
加入location /test,我們故意把位置放到location /以下,來驗證優(yōu)先級。請求結果如下,返回401,從結果可以看出來/test的優(yōu)先級高于location /。不過用戶的訪問要以/test開頭,不是以/test開頭還是命中到location /:
location正則的優(yōu)先級測試,我們加入~ ^/test,使用正則匹配以test開頭的
location / {
return 400;
}
location /test {
return 401;
}
location ~ ^/test {
return 402;
}
加入location ~ ^/test,我們故意再把它放到最后,來驗證優(yōu)先級。請求結果如下,返回402,從結果可以看出來正則的優(yōu)先級要大于location /和location /test,也就是正則location大于通配location
多個正則的優(yōu)先級測試,我們使用兩個正則,主要是來驗證下,是不是正則配置得越多,優(yōu)先級就越高。如下的配置
location ~ ^/test {
return 402;
}
location ~ ^/test/aaa {
return 403;
}
加入^/test/aaa,我們一樣把它放到最后,請求/test/aaa。結果返回402,也就是匹配到第一個正則后,底下的正則不會再去匹配。由于請求/test/aaa,命中^/test,所以底下的正則就無效了:
我們加入精準匹配,也就是nginx的=,我們來測試下精準匹配的優(yōu)先級
location ~ ^/test/aaa {
return 403;
}
location = /test/aaa {
return 404;
}
我們故意把= /tmp/aaa放到最后,這個只能匹配到/test/aaa的請求,得到的結果如下,返回404。這個說明了,精準匹配=的優(yōu)先級是最高的,不管它放到哪里。
問題1:為什么我的nginx設置了全局跳轉,但怎么不生效?
location / {
rewrite xxx xxxx;
}
location ~* ^/test {
return 402;
}
如果是以上的跳轉配置的話,大家根據優(yōu)先級來,可以發(fā)現location /的優(yōu)先級是最低的,所以全局跳轉不生效。因為當用戶訪問到/test/xx的時候,命中到其它location了。所以全局跳轉的話,保留一個location /即可。
問題2:為什么我的nginx動靜分離配置失敗了?
location ~ ^/test {
root xxxx;
}
location ~ .jsp$ {
proxy_pass xxxx;
}
如果是以上配置的話,當用戶訪問到/test/xxx.jsp的時候,就命令到location ~ ^/test了。所以動靜分離如果都使用正則的話,需要注意location的放置位置。
總結如下:
1 匹配優(yōu)先級如下
① = 精確匹配
② ^~ 優(yōu)先匹配常規(guī)字符串,匹配后,不檢查正則
③ ~* 正則匹配 示例: ~*.(gif|jpg|jpeg)$
④ / documents/ 匹配常規(guī)字符 documents 代表目錄,可以是其他值
⑤ / 所有l(wèi)ocation無法匹配,則顯示該默認匹配
以上可以都有,也可以都沒有,如果都有,則按照以上優(yōu)先級匹配。
2 匹配的時候如果有正則,如上面③的示例,則網址最后一項是.gif 即可匹配成功,在.gif前面的目錄是不存在的也能匹配。
/documents 如果要匹配成功,上級目錄必須是存在的。
3 正則寫法必須有~或~* 否則無效