學了Nginx的反向代理和負載均衡之后,了解的基本的原理,在實際項目部署中其中更多的要知道如何去靈活的去運用這些東西,其中很重要的就是Location匹配原則。
0.常見的正則表達式符號
| 符號 | 含義 |
|---|---|
| $ | 匹配輸入字符串的結(jié)尾位置 |
| ( ) | 標記一個子表達式的開始和結(jié)束位置 |
| * | 匹配前面的子表達式一次或多次 |
| ^ | 匹配輸入字符串的開始位置 |
| \ | 將下一個字符標記為或特殊字符、或原義字符、或向后引用、或八進制轉(zhuǎn)義符 |
| | | 指明兩項之間的一個選擇 |
| . | 匹配除換行符 \n 之外的任何單字符 |
| ? | 匹配前面的子表達式零次或一次,或指明一個非貪婪限定符 |
| ~ | 表示執(zhí)行一個正則匹配,區(qū)分大小寫 |
如果要匹配以上的特殊字符就需要在前面加個轉(zhuǎn)義字符
\就可以了,**小括號()之間匹配的內(nèi)容,可以在后面通過$1來引用,$2表示的是前面第二個()里的內(nèi)容 ,正則表達式可以包含可供以后在$1..$9變量中重復使用的捕獲 **
1.基本語法
1.Nginx Location配置語法
1. location [ = | ~ | ~* | ^~ ] uri { ... }
2. location @name { ... }
2.location配置可以有兩種配置方法
1.前綴 + uri(字符串/正則表達式)
2.@ + name
3.前綴含義
| 模式 | 含義 |
|---|---|
| location = /uri | = 表示精確匹配,只有完全匹配上才能生效 |
| location ^~ /uri | ^~ 開頭對URL路徑進行前綴匹配,并且在正則之前。 |
| location ~ pattern | 開頭表示區(qū)分大小寫的正則匹配 |
| location ~* pattern | 開頭表示不區(qū)分大小寫的正則匹配 |
| location /uri | 不帶任何修飾符,也表示前綴匹配,但是在正則匹配之后 |
| location / | 通用匹配,任何未匹配到其它location的請求都會匹配到,相當于switch中的default |
前綴匹配時,Nginx 不對 url 做編碼,因此請求為 /static/20%/aa,可以被規(guī)則 ^~ /static/ /aa 匹配到(注意是空格)
多個 location 配置的情況下匹配順序為(與location在配置文件中的順序無關(guān) ,僅供參考):
- 首先精確匹配
= - 其次前綴匹配
^~ - 其次是按文件中順序的正則匹配
- 然后匹配不帶任何修飾的前綴匹配。
- 最后是交給
/通用匹配 - 當有匹配成功時候,停止匹配,按當前匹配規(guī)則處理請求
注意:前綴匹配,如果有包含關(guān)系時,按最大匹配原則進行匹配。比如在前綴匹配:location /dir01 與 location /dir01/dir02,如有請求 http://localhost/dir01/dir02/file 將最終匹配到 location /dir01/dir02
4.location基礎(chǔ)知識
- location是在server塊中匹配的。
- 可以根據(jù)不同的URL使用不同的配置(location中配置),來處理不同的請求。
- location是有順序的,會被第一個匹配的location處理。
2.location實例
1.基本匹配實例
**普通匹配,遵循最長匹配規(guī)則,假設(shè)一個請求匹配到了兩個普通規(guī)則,則選擇匹配長度大的那個 **
例如:
location /{
[matches]
}
location /test{
[matches]
}
**精確匹配 **
location = /{
[matchtes]
}
location = /test{
[matches]
}
**正則匹配 **
~ 區(qū)分大小寫的匹配
location ~ ^*.php${
[matches]
}
~* 不區(qū)分大小寫的匹配
location ~* ^*.php${
[matches]
}
^~ 普通字符匹配,如果請求匹配此規(guī)則,則其他規(guī)則忽略,只匹配該規(guī)則
location ^~ /test{
[matches]
}
@locationname 內(nèi)部redirect匹配
location @locationname{
[matches]
}
匹配優(yōu)先級:
? 首先檢查是否有精確匹配規(guī)則,如果有,則處理精確匹配規(guī)則,假設(shè)發(fā)現(xiàn)精確匹配規(guī)則,停止搜索其他匹配規(guī)則,返回當前匹配的規(guī)則
其次普通字符匹配,該項匹配請求,仍然需要檢查是否有正則或者更長匹配,如果有,返回正則匹配或者更長匹配
^~匹配被第三步處理,如果請求匹配此規(guī)則,停止其他規(guī)則匹配,返回此規(guī)則
正則匹配被最后執(zhí)行,正則匹配只要被找到,停止解析其他規(guī)則,這個就要注意先后順序了
2.完整的例子
location = / {
# 只匹配"/".
[ configuration A ]
}
location / {
# 匹配任何請求,因為所有請求都是以"/"開始
# 但是更長字符匹配或者正則表達式匹配會優(yōu)先匹配
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 開始的請求,并停止匹配 其它location
[ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配以 gif, jpg, or jpeg結(jié)尾的請求.
# 但是所有 /images/ 目錄的請求將由 [Configuration C]處理.
[ configuration D ]
}
請求URI例子:
/ -> 符合configuration A
/documents/document.html -> 符合configuration B
/images/1.gif -> 符合configuration C
/documents/1.jpg ->符合 configuration D
@location 例子
error_page 404 = @fetch;
location @fetch{
proxy_pass http://fetch;
}
3.實際使用規(guī)則
#所以實際使用中,個人覺得至少有三個匹配規(guī)則定義,如下:
#直接匹配網(wǎng)站根,通過域名訪問網(wǎng)站首頁比較頻繁,使用這個會加速處理,官網(wǎng)如是說。
#這里是直接轉(zhuǎn)發(fā)給后端應用服務器了,也可以是一個靜態(tài)首頁
# 第一個必選規(guī)則
location = / {
proxy_pass http://tomcat:8080/index
}
# 第二個必選規(guī)則是處理靜態(tài)文件請求,這是nginx作為http服務器的強項
# 有兩種配置模式,目錄匹配或后綴匹配,任選其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
#第三個規(guī)則就是通用規(guī)則,用來轉(zhuǎn)發(fā)動態(tài)請求到后端應用服務器
#非靜態(tài)文件請求就默認是動態(tài)請求,自己根據(jù)實際把握
#畢竟目前的一些框架的流行,帶.php,.jsp后綴的情況很少了
location / {
proxy_pass http://tomcat:8080/
}
4.Location下的root路徑規(guī)則
alias 指定的目錄是準確的,給location指定一個目錄。
root 指定目錄的上級目錄,并且該上級目錄要含有l(wèi)ocatoin指定名稱的同名目錄
location /img/ {
alias /var/www/image/;
}
#若按照上述配置的話,則訪問/img/目錄里面的文件時,ningx會自動去/var/www/image/目錄找文件
#注意:
#1. 使用alias時,目錄名后面一定要加"/"。
#2. alias在使用正則匹配時,必須捕捉要匹配的內(nèi)容并在指定的內(nèi)容處使用。
#3. alias只能位于location塊中。(root可以不放在location中)
location /img/ {
root /var/www/image;
}
#若按照這種配置的話,則訪問/img/目錄下的文件時,nginx會去/var/www/image/img/目錄下找文件
#用root來設(shè)置前端非根目錄時,nginx會組合root和location的路徑
5.參考資料
https://segmentfault.com/a/1190000009651161
https://gist.github.com/luxixing/7262911
http://nginx.org/en/docs/http/ngx_http_core_module.html#location