nginx反向代理

什么是反向代理

在我看來,反向代理的過程就像運輸快遞,反向代理服務器就是小區(qū)里的菜鳥驛站或蜂巢,賣家就是客戶端,買家就是服務端。賣家(客戶端)發(fā)出去菜鳥驛站(代理服務器)的請求,菜鳥驛站(代理服務器)接收到請求后,再根據(jù)請求里的信息,菜鳥驛站(代理服務器)根據(jù)特定的規(guī)則將快遞分發(fā)給不同的買家(服務端)。圖解:
圖解

如何實現(xiàn)反向代理

要實現(xiàn)反向代理服務器首先就需要一個反向代理服務器,目前常用的反向代理服務器有Nginx、HAproxy等等,各有優(yōu)劣。這里我使用nginx來作為反向代理服務器。

準備工作以及安裝nginx

這里我用Ubuntu環(huán)境演示,版本為20.04
sudo apt-get install nginx
安裝完成后用命令`nginx -v`來檢查是否安裝成功,如果出現(xiàn)版本信息就說明已經(jīng)安裝成功,我的環(huán)境里的nginx版本信息如下
nginx version: nginx/1.18.0 (Ubuntu)
然后我在我的環(huán)境里新建兩個web服務器serve1和seve2,serve1的地址為`localhost:8001`,serve2的地址為`localhost:8002`,訪問這兩個服務器分別返回當前請求的url,如圖
serve1
serve2

配置nginx

安裝完成后就可以進行配置了,配置文件的目錄是`/etc/nginx/nginx.conf`,打開這個文件
sudo /etc/nginx/nginx.conf   # 如果沒有修改這個文件的所有者或者讀寫權限的話就需要用root賬戶打開

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;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

要實現(xiàn)反向代理,就需要在http下的server里進行配置。

具體配置如下:

...
http {
    ...
    server {
        listen 8974;                            # nginx的監(jiān)聽端口
        server_name localhost;                  # nginx的監(jiān)聽地址
                                               
        location /serve1 {                      # nginx的路由配置,也是配置反向代理的地方, 可以精確匹配也可以寫正則表達式
            proxy_pass http://localhost:8001;    # 需要nginx代理的服務器
        }
        
        location /serve2 {                      # 可以定義多個路由配置
            proxy_pass http://localhost:8002;
        }
    }
}

目前這樣就已經(jīng)算是簡單的配置完了一個反向代理規(guī)則,然后啟動nginx服務器,直接在終端輸入nginx,然后訪問http://localhost:8974/serve1,nginx接收到請求后,根據(jù)配置好的規(guī)則:如果以/serve結尾,則請求就被轉發(fā)到http://localhost:8001,轉發(fā)的完整請求是http://localhost:8001/serve1,serve2同理。

轉發(fā)請求

rewrite路徑重寫

有時候請求的URI在轉發(fā)時想修改下,就需要用到rewrite,rewrite會根據(jù)正則表達式重寫URI,rewrite的格式如下:
rewrite  reg     replace   flag
# reg就是進行匹配時的規(guī)則
# replace會將reg匹配的內容替換掉
# rewrite的標記說明,分別為:
    last(讓當前rewrite為最后一個rewrite,不再匹配后邊的rewrite規(guī)則)、
    break(讓當前l(fā)ocation為最后一個location,不再匹配后邊的location規(guī)則)、
    redirect(返回302臨時重定向)、
    permanent(返回301永久重定向)

比如說我請求的是http://localhost:8974/serve1/test1/test2,然后我想重寫成http://localhost:8001/test1/test2,也就是用/test1/test2替換/serve1/test1/test2,所以rewrite就該這樣寫:

...
http {
    ...
    server {
        listen 8974;                            # nginx的監(jiān)聽端口
        server_name localhost;                  # nginx的監(jiān)聽地址
                                               
        location /serve1 {                      # nginx的路由配置,也是配置反向代理的地方, 可以精確匹配也可以寫正則表達式
            proxy_pass http://localhost:8001;    # 需要nginx代理的服務器
             rewrite '/serve1(.*)$' '$1' break;   # 重寫的規(guī)則
        }
        
        location /serve2 {                      # 可以定義多個路由配置
            proxy_pass http://localhost:8002;
             rewrite '/serve2(.*)$' '$1' break;
        }
    }
}

reg部分為/serve1(.*)$,這個正則表達式匹配/serve1和其后邊的所有字符,其中(.*)為匹配括號內所有字符并提取其值。

replace部分為$1,其表示reg部分用圓括號提取的值。

所以如果請求是http://localhost:8974/serve1/test1/test2,根據(jù)匹配規(guī)則,會先匹配出/serve1/test1/test2,其中/test1/test2被提取出來,然后用提取出來的值/test1/test2替換匹配到的/serve1/test1/test2。所以轉發(fā)后的請求就變成了http://localhost:8001/test1/test2。

重寫URI

常用正則表達式說明

字符 說明
\ 將其后變的字符從關鍵字變成普通字符
^ 匹配輸入字符的起始位置
$ 匹配輸入字符的結束位置
* 匹配其前邊字符零次或多次
+ 匹配其前邊字符一次或多次
? 匹配其前邊字符零次或一次
. 匹配除換行符外的所有字符
() 匹配括號內的內容并提取之,在后邊可以用1至9獲取提取的內容
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容