Nginx配置?location模塊實(shí)現(xiàn)路由(反向代理、重定向)功能
前置文章:
Linux(CentOS7) 下 Nginx1.15.8 安裝步驟
我們?cè)L問(wèn)一個(gè)網(wǎng)址,服務(wù)器返回對(duì)應(yīng)的資源。那么一個(gè)網(wǎng)址是如何對(duì)應(yīng)一個(gè)資源的呢?
用 Nginx 可以很好地幫我們實(shí)現(xiàn)路由功能,我們所有需要做的就是配置好 location 模塊。
語(yǔ)法規(guī)則
location [=|~|~*|^~] /uri/ {… }
符號(hào) | 含義 |
= | 精確匹配 |
^~ | 非正則匹配 |
~ | 正則匹配(區(qū)分大小寫) |
~* | 正則匹配(不區(qū)分大小寫) |
!~ | 正則不匹配(區(qū)分大小寫) |
!~* | 正則不匹配(不區(qū)分大小寫) |
普通匹配(這里沒(méi)有符號(hào)的時(shí)候) |
匹配規(guī)則
1. 精準(zhǔn)匹配命中時(shí),停止location
2.一般匹配(普通和非正則)命中時(shí),對(duì)比所有命中的一般匹配,選出最長(zhǎng)的一條
3.如果最長(zhǎng)的那一條為非正則匹配,直接匹配此條,停止location
4.如果最長(zhǎng)的那一條為普通匹配,繼續(xù)嘗試正則location(以上至此都不存在代碼順序)
5.按代碼順序執(zhí)行正則匹配,當(dāng)?shù)谝粭l正則location命中時(shí),停止location
示例:
想運(yùn)行以下示例需先下載第三方模塊echo-nginx-module:
#下載到/usr/local/src目錄 wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz tar -zxvf v0.61.tar.gz ? ? ? ? ? ? ? ??? ? ? ? ? ? ? ?? #在Nginx源碼目錄nginx-1.15.8下配置,--add-module指向模塊目錄即會(huì)安裝插件到nginx中 ./configure --add-module=/usr/local/src/echo-nginx-module-0.61/ make && make install #驗(yàn)證安裝 nginx -V
你還需要配置 C:\Windows\System32\drivers\etc\hosts 文件,添加“虛擬機(jī)ip 域名”到最后:
192.168.100.14 test.loaction.com
server { listen 80; server_name test.location.com; #精準(zhǔn)匹配測(cè)試 #第1,2條雖然匹配,但第三條是精準(zhǔn)匹配,出第三條結(jié)果 #測(cè)試路徑/equal/a/b/c location ~ /equal/* { echo '/equal/*'; } location /equal/a/b { echo '/equal/a/b'; } location = /equal/a/b/c { echo '/equal/a/b/c'; } #普通匹配測(cè)試 #第1,2條雖然匹配,第三條匹配更長(zhǎng),出第三條結(jié)果 #測(cè)試路徑/match/a/b/c location /match/a { return 200 "/match/a"; } location /match/a/b { return 200 "/match/a/b"; } location /match/a/b/c { return 200 "/match/a/b/c"; } location /match/a/b/c/d { return 200 "/match/a/b/c/d"; } #正則匹配覆蓋普通匹配,不會(huì)覆蓋非正則匹配 #訪問(wèn)/re/a.htm,會(huì)被后面的正則覆蓋 #訪問(wèn)/re/a/b開(kāi)頭的路徑,不會(huì)被后面的正則覆蓋 location /re/a.htm { echo 'match /re/a.htm'; } location ^~ /re/a/b { echo 'math ^~/re/a/b*'; } location ~ /re/(.*)\.(htm|js|css)$ { echo "cover /re/$1.$2"; } #正則匹配成功一條后,便不再走其它正則 #測(cè)試路徑/rex/a/b/c.htm location ~ /rex/.*\.(htm|js|css)$ { echo "match first"; } location ~ /rex/a/(.*)\.(htm|js|css)$ { echo "match second"; } location ~ /rex/a/b/(.*)\.(htm|js|css)$ { echo "match third"; } }
結(jié)果:
精準(zhǔn)匹配最優(yōu)先:
一般匹配選最長(zhǎng):
正則覆蓋普通匹:
不能覆蓋非正則
正則匹配選首位:
proxy_pass 代理轉(zhuǎn)發(fā)
在上面的示例中,我們通過(guò)修改本機(jī)hosts文件,讓本機(jī)訪問(wèn) test.loaction.com 相當(dāng)于訪問(wèn) 192.168.100.14。我們現(xiàn)在假設(shè)有一個(gè)服務(wù)在 192.168.100.15 這臺(tái)機(jī)器上。我們能不能通過(guò)訪問(wèn) test.loaction.com,訪問(wèn)到 192.168.100.15 上的資源呢?
這樣的想法其實(shí)是在模擬實(shí)際做項(xiàng)目的時(shí)候,我們可以只購(gòu)買一個(gè)域名,然后訪問(wèn)多個(gè)云服務(wù)器。我們要做的就是讓域名對(duì)應(yīng)的服務(wù)器具有代理轉(zhuǎn)發(fā)的功能。這里是服務(wù)器作為代理,讓客戶端能通過(guò)訪問(wèn)代理服務(wù)器來(lái)訪問(wèn)其它服務(wù)器,所以是反向代理。
通過(guò)在 location 里配置 proxy_pass 就能實(shí)現(xiàn)代理轉(zhuǎn)發(fā)功能,幫助我們將請(qǐng)求轉(zhuǎn)發(fā)到別的服務(wù)器。
我們先看示例再看規(guī)則:
server { listen 80; server_name test.location.com; 本機(jī)ip地址:192.168.100.104 #后端服務(wù)路徑: http://192.168.100.105:8080/user/query?id=1 #規(guī)則一: #訪問(wèn)路徑:http://test.location.com/user/query?id=1 location /user { #path1:/user path2:/query #ip:port 后面無(wú) / proxy_pass http://192.168.0.105:8080; } 規(guī)則二: #訪問(wèn)路徑 :http://test.location.com/A/user/query?id=1 location /A/user { #path1:/A/user path2:/query #ip:port 后面有 /xxx proxy_pass http://192.168.0.105:8080/user; } }
解讀:
后端服務(wù)路徑都是 http://192.168.100.105:8080/user/query?id=1。用規(guī)則一,可以使訪問(wèn)路徑為 http://test.location.com/user/query?id=1;用規(guī)則二,可以使訪問(wèn)路徑為 http://test.location.com/A/user/query?id=1。
規(guī)則:
1. 訪問(wèn)路徑格式為 sever_name + path1 + path2 + ?param
2. location 后面的路徑就是 path1,對(duì)照訪問(wèn)路徑格式,path1 和 ?param 之間的為path2
3. 如果 proxy_pass 后面的值形如 http: // ip : port; 那么實(shí)際訪問(wèn)的地址是 http: // ip : port + path1 + path2 + ?param
4. 如果 proxy_pass 后面的值形如 http: // ip : port / xxx; (末尾相比上面有 /xxx)
那么實(shí)際訪問(wèn)的地址是 http: // ip : port + path2 + ?param
規(guī)則二的作用:
如果我們?cè)L問(wèn)其它服務(wù)器都使用規(guī)則一,那么我們將無(wú)法直觀地從 URL 確定這個(gè)服務(wù)屬于那臺(tái)機(jī)器或者哪種服務(wù)。
而如果使用規(guī)則二,我們可以通過(guò)合理的設(shè)置明確地知道,我們?cè)L問(wèn)的是服務(wù)A。
root 與 index
nginx.conf 里的默認(rèn) location 如下:
location / { root html; index index.html; }
意思是資源文件的根目錄在 nginx 程序所在文件夾下的 html 文件夾:
如果我們沒(méi)有寫 URI,默認(rèn)的資源是 html 文件夾下的 index.html
但是你如果這樣配置:
location / { root html; index index.html; } location /index.html { echo "index"; }
最后訪問(wèn) http://test.location.com/ 瀏覽器會(huì)輸出 index:
也就是說(shuō),雖然前面設(shè)置了 index ,但是如果它對(duì)應(yīng)的地址有被 location 匹配到的話,會(huì)執(zhí)行 location 匹配后的結(jié)果。
但是,必須還是得有 index 對(duì)應(yīng)的文件。
為了驗(yàn)證上面這一點(diǎn),我把 html 目錄下的 index.html 改成 index,再 reload 并訪問(wèn):
root 與 alias
還是先看示例比較直觀:
server { listen 80; server_name test.local.com; #文件地址:/etc/nginx/html/static/a.html #訪問(wèn)路徑:http://test.local.com/static/a.html location /static { #path1:/static path2:/a.html root /etc/nginx/html/; #文件地址:root + path1 + path2 } #訪問(wèn)路徑:http://test.local.com/target/a.html location /target { #path1:/target path2:/a.html alias /etc/nginx/html/static/; #文件地址:alias + path2 } }
解讀:
文件地址一樣,訪問(wèn)路徑可以不同。
使用 root 聲明的是根目錄,經(jīng)過(guò) location 匹配后,直接去根目錄下找訪問(wèn)路徑中 sever_name 后面的文件地址。
使用 alias 聲明的是別名目錄,經(jīng)過(guò) location 匹配后,去別名目錄下找訪問(wèn)路徑中 sever_name 后面除去 location 匹配的地址的剩余地址。這就好像給 location 匹配的地址取了個(gè)別名一樣。
規(guī)則:
1. 訪問(wèn)路徑格式為 sever_name + path1 + path2
2. location 后面的路徑就是 path1,對(duì)照訪問(wèn)路徑格式,path1 后面的就是 path2
3. 如果使用 root ,文件地址為:
root + path1 +path2
4. 如果使用 alias ,文件地址為:
alias + path2
location 執(zhí)行過(guò)程
結(jié)合以上內(nèi)容,就很容易理解 location 執(zhí)行過(guò)程了,如下圖
rewrite 重定向
location 里還可以配置 rewrite 實(shí)現(xiàn)重定向:
rewrite regex replacement [flag];
其中:
regex:正則表達(dá)式
replacement :替換值flag:后續(xù)處理標(biāo)識(shí),可以為 break/last/permanent/redirect
重點(diǎn)在于 flag :
1. flag=break
發(fā)生 nginx 內(nèi)部重定向,path值被更新,rewrite層面的命令會(huì)中斷。原控制流程邏輯不變往下走
2. flag=last
發(fā)生nginx內(nèi)部重定向,path值被更新,rewrite層面的命令會(huì)中斷。控制流程刷新,重新進(jìn)行整個(gè)location層的邏輯流程
3. flag= permanent/redirect
發(fā)生頁(yè)面重定向(301永久重定向/302臨時(shí)重定向),nginx流程結(jié)束,返回http響應(yīng)到瀏覽器,頁(yè)面url更新
4.flag為空
發(fā)生nginx內(nèi)部重定向,path值被更新,rewrite層面的命令繼續(xù)。最后一個(gè)rewrite完畢,刷新控制流程,重新進(jìn)行l(wèi)ocation重匹配
示例:
server { listen 80; server_name test.location.com; location /a.html { echo 'I am a.html'; } location /b.html { echo 'I am b.html'; } #此路徑請(qǐng)求:http://test.location.com/aa.html location /aa.html {##內(nèi)部重定向 rewrite ^/ /a.html break;##不會(huì)執(zhí)行下面的rewrite rewrite ^/ /b.html break; root /etc/nginx/html/; } #此路徑請(qǐng)求:http://test.location.com/ab.html location /ab.html {##內(nèi)部重定向 rewrite ^/ /a.html last;##不會(huì)執(zhí)行下面的rewrite,但重新location匹配 rewrite ^/ /b.html last; rewrite ^/ /c.html; root /etc/nginx/html/; } #此路徑請(qǐng)求:http://test.location.com/ba location /ba { rewrite ^/ /b.html permanent;##301永久重定向 root /etc/nginx/html/; } #此路徑請(qǐng)求:http://test.location.com/bb location /bb { rewrite ^/ /b.html redirect;##302臨時(shí)重定向 set $aa 12; root /etc/nginx/html/; } #此路徑請(qǐng)求:http://test.location.com/cc.html location /cc.html { rewrite ^/ /c.html;##指令不停,繼續(xù)往下 rewrite ^/ /b.html; rewrite ^/ /a.html;##最后一條,生效的是這條 root /etc/nginx/html/; } }
結(jié)果:
訪問(wèn) http://test.location.com/aa.html,直接尋找 root 目錄下的 a.html,我沒(méi)有寫這個(gè) html,所以是 404
訪問(wèn) http://test.location.com/ab.html,因?yàn)橹匦?location 匹配了,所以匹配到了上面的 /a.html,輸出了一句話
訪問(wèn) http://test.location.com/ba,永久重定向,可以看到地址欄的網(wǎng)址都變了,是外部重定向
訪問(wèn) http://test.location.com/bb,臨時(shí)重定向
訪問(wèn) http://test.location.com/cc.html,不是 404,也經(jīng)過(guò)了重新 location 匹配
Nginx 處理請(qǐng)求的11個(gè)階段
Nginx 處理請(qǐng)求的全過(guò)程一共劃分為 11 個(gè)階段(如圖),按階段由上到下依次執(zhí)行 (上一階段的所有指令執(zhí)行完畢,才進(jìn)入下一階段)
各階段的含義如下:
- post_read: 接收到完整的 http 頭部后處理的階段,在uri重寫之前。一般跳過(guò)
- server_rewrite: location匹配前,修改uri的階段,用于重定向,location塊外的重寫指令(多次執(zhí)行)
- find_config: uri 尋找匹配的location塊配置項(xiàng)(多次執(zhí)行)
- rewrite:找到location塊后再修改uri,location級(jí)別的uri重寫階段(多次執(zhí)行)
- post_rewrite:防死循環(huán),跳轉(zhuǎn)到對(duì)應(yīng)階段
- preaccess: 權(quán)限預(yù)處理
- access:判斷是否允許這個(gè)請(qǐng)求進(jìn)入
- post_access: 向用戶發(fā)送拒絕服務(wù)的錯(cuò)誤碼,用來(lái)響應(yīng)上一階段的拒絕
- try_files: 訪問(wèn)靜態(tài)文件資源
- content : 內(nèi)容生成階段,該階段產(chǎn)生響應(yīng),并發(fā)送到客戶端
- log:記錄訪問(wèn)日志
到此這篇關(guān)于Nginx配置 location模塊實(shí)現(xiàn)路由(反向代理、重定向)功能的文章就介紹到這了,更多相關(guān)Nginx location 路由反向代理和重定向內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Nginx反向代理多域名的HTTP和HTTPS服務(wù)的實(shí)現(xiàn)
這篇文章主要介紹了Nginx反向代理多域名的HTTP和HTTPS服務(wù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06使用Docker實(shí)現(xiàn)Nginx反向代理
本文主要介紹了使用Docker實(shí)現(xiàn)Nginx反向代理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06nginx將https協(xié)議反向代理到http協(xié)議請(qǐng)求上的實(shí)現(xiàn)
本文主要介紹了nginx將https協(xié)議反向代理到http協(xié)議請(qǐng)求上的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-10-10nginx加php-fpm出現(xiàn)502 bad gateway錯(cuò)誤的5種解決方法
這篇文章主要介紹了nginx加php-fpm環(huán)境中出現(xiàn)502 bad gateway錯(cuò)誤的5種解決方法,總結(jié)歸納服務(wù)器出現(xiàn)502錯(cuò)誤的原因多數(shù)為連接過(guò)多和腳本超時(shí),本文總結(jié)了5種解決方法,需要的朋友可以參考下2014-05-05Nginx的location的常見(jiàn)規(guī)則優(yōu)先級(jí)問(wèn)題
Nginx是反向代理和負(fù)載均衡的首選工具,nginx的location配置有許多細(xì)節(jié)內(nèi)容在網(wǎng)上不容易找到資料,或者解釋不清。本文對(duì)Nginx location規(guī)則優(yōu)先級(jí)介紹,需要的朋友參考下吧2021-08-08詳解Nginx的配置函數(shù)對(duì)于請(qǐng)求體的讀取
這篇文章主要介紹了Nginx的配置函數(shù)對(duì)于請(qǐng)求體的讀取,深入Nginx的內(nèi)核配置中進(jìn)行講解,需要的朋友可以參考下2015-12-12