Nginx 學習系列(一) ------------- 正向代理與反向代理

擁抱心中的夢想發表於2018-08-06

今天花點時間記錄下nginx的反向代理知識,之前也是有用過,但是我覺得還是依舊簡單地記錄下來,好記性不如爛筆頭,說不定你以後學了新知識,又把它忘記了,回過頭想重新學習,又得百度一下這找部落格,那找部落格,學習成本多大呀!

1、正向代理和反向代理的概念

無論是正向代理,還是反向代理,說到底,就是代理模式的衍生版本罷了。我們都學習過代理設計模式,都知道代理模式中有代理角色和被代理角色,為什麼這麼說,因為這兩個角色對於我們理解正向和反向代理非常重要,下面會講到。

下面我將引入這樣一個場景,很多時候我們上網的網速特別慢,或者說由於翻牆問題導致我們無法訪問到國外的網站,通常這些情況我們會通過給瀏覽器配置一個網速快的、可以翻牆的代理ip及埠號來解決我們的問題,那麼配置好之後,大概的請求流程如下圖所示:

Nginx 學習系列(一) -------------   正向代理與反向代理

我們首先請求代理伺服器,然後代理伺服器幫我們去快速訪問國外的網站,對於這種代理方式,我們就稱之為正向代理。請記住,上面說到代理模式的兩個角色中,我們當前的角色為 被代理者,也就是瀏覽器這個角色。更重要的是,正向代理的本質是我們去請求外部的資源,如果以生產者、消費者模式來區分,我們屬於消費者。

總結:

  • 1、正向代理,我們的角色是 被代理者
  • 2、正向代理,我們不對外提供服務,反而是對外消費服務,屬於消費者

反向代理,很顯然,就是和正向代理相反,如果說正向代理是男,那麼反向代理就是女了,親,此處不再糾結其他情況!下面我用一副圖片解釋下反向代理:

Nginx 學習系列(一) -------------   正向代理與反向代理

看完上面的圖片,請你想象一下這麼一個場景,假設你現在是某公司技術總監,你們公司需要對外提供一套web服務,那麼你打算怎麼做呢?

答案是可以通過反向代理來完成。通常你們公司擁有自己的IDC機房,機房通訊通常採用區域網交換機,internet網使用者請求是無法直接訪問到區域網內的web服務的,因此這個時候,你需要一臺反向代理伺服器來接收internet web請求,然後將請求分發到區域網中的不同主機上進行處理,處理完成之後再做出響應。因此,反向代理大概就是這麼一個場景。請記住,反向代理中,我們的角色是 區域網 web服務

總結:

  • 1、反向代理,我們的角色是 區域網 web服務
  • 2、反向代理,我們對外提供服務,屬於服務提供者

2、nginx正向代理和反向代理例項解析

nginx在正向代理方面的應用非常地少,因此,對於正向代理的相關配置指令也不多,下面是一個nginx作為正向代理伺服器的配置例項,配置僅供參考。

server {  
    resolver 192.168.1.1; #指定DNS伺服器IP地址  
    listen 8080;  
    location / {  
        proxy_pass http://$http_host$request_uri; #設定代理伺服器的協議和地址  
    }  
}  
複製程式碼

解釋下上面的指令,resolver配置DNS伺服器的ip地址,可以配置多個。你可能會問,正向代理中為什麼需要配置DNS伺服器的ip地址呢?其實答案很簡單,你想象下假如現在你的瀏覽器配置了正向代理伺服器,你現在在瀏覽器中輸入http://oneSite.cn/index.html,根據正向代理原理,該url請求將會被正向代理伺服器執行,問題來了,如果你的代理伺服器不配置DNS解析服務,nginx怎麼知道你這個oneSite.cn到底是個什麼鬼,到底對應因特網的ip地址是什麼?所以這就是需要配置resolver指令的原因所在。

listen指令配置nginx監聽瀏覽器請求的埠號。

proxy_pass指令配置接收到被代理瀏覽器發來的請求之後,需要幫忙執行的請求是什麼,$http_host$request_uri指明目的主機和uri,屬於nginx變數,一般不需要修改。

nginx反向代理的相關配置如下,在這裡小編搭建兩個Spring boot小demo模擬上面反向代理的web服務,相關原始碼可以在github獲取。

Nginx 學習系列(一) -------------   正向代理與反向代理

demo工程啟動埠號為8081,demo1工程啟動埠為8082,對於所有的請求字首帶/demo的都將轉發到demo工程進行處理,對於所有的請求字首帶/demo1的都將轉發到demo1工程進行處理。

nginx配置如下:

server {
    listen       80;
    location /demo {
        proxy_pass http://127.0.0.1:8081;
    }
    location /demo1 {
        proxy_pass http://127.0.0.1:8082;
    }
}
複製程式碼

啟動demodemo1兩個工程之後,瀏覽器輸入下面地址:

Nginx 學習系列(一) -------------   正向代理與反向代理

Nginx 學習系列(一) -------------   正向代理與反向代理

可以看到,外部統一使用80埠訪問服務時,nginx根據路徑字首進行代理,然後返回執行結果。對於nginx反向代理路徑配置有幾點需要注意,使用時要非常謹慎。

上面proxy_pass指令配置的url為http://127.0.0.1:8081,注意在該url後面不能使用/demo1字尾進行代替,否則就報錯了。為什麼呢?首先nginx會判斷proxy_pass指令中配置的url地址是否包含uri,如果在proxy_pass指令中配置的url地址不包含uri,那麼nginx將會使用請求路徑的uri進行轉發,如果在proxy_pass指令中配置的url地址包含uri,則nginx會忽略請求location中的uri,轉而使用你在proxy_pass中配置的uri進行覆蓋,轉發,另外,/也是一種uri,哈哈,要特別小心哈~

舉例子:

假設請求地址為:http://localhost/demo/getServerInfo.json,location配置為/demo,proxy_pass配置為http://xxxx:port,則會使用http://xxxx:port/demo/getServerInfo.json進行轉發,結果正確。如果proxy_pass配置為http://xxxx:port/demo1,則會使用http://xxxx:port/demo1進行轉發,因為/demo1覆蓋了/demo

相關文章