日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

【Nginx27】Nginx學習:代理模塊(一)基本配置與概念

 硬核項目經理 2023-09-18 發(fā)布于湖南

Nginx學習:代理模塊(一)基本配置與概念

來了來了它來了。要說 Nginx 最早最出名的名頭是什么?相信不少老碼農馬上就會想到,最開始,Nginx 的名頭就是一款性能最高的 反向代理 服務器。現在其實也是,但是這么說的人越來越少了。也就是說,其實 Nginx 最主要的功能就在于反向代理。如果是編程小白,剛剛從事編程相關工作,沒有配置過負載集群,可能對這個概念還是比較陌生的。那么今天咱們就來先說說 代理、反向代理、正向代理 這些概念。

今天的內容只有一個配置指令,只能用在 location 中。

代理

代理是啥意思,之前我們老早就學過的設計模式系列的文章中,就講過一個 代理模式 的應用。說實話,Nginx 中的代理模塊其實也是代理模式思維的一個體現。還記得代理模式的定義嗎?

為其它對象提供一種代理以控制對這個對象的訪問

從編程語言的角度來說,就是我們要訪問一個對象,但是可能由于種種原因不能直接訪問它,這就要通過代理來實現訪問。這個代理相當于是中間的一個媒介,可以幫我們做一些事情,也可以想像是我們和要使用的對象之間的橋梁。

當時我們也舉了一個例子,現在也可以用這個例子,那就是買房子或者買保險,不管是房產中介還是保險銷售,其實都可以稱為代理人。他們用他們專業(yè)的知識幫我們解決問題,甚至買房或者租房都可以不用和房主產生交集,但真正在處理這個房產證的,其實還是房主(保險公司)。

這個就是代理,說起來很抽象是吧,大家都是碼農,可以先通過代碼去了解,小伙伴們可以回到 PHP設計模式之代理模式https://mp.weixin.qq.com/s/0CvVMuP-_j-0sqRK_4kcZA 這篇文章中再重溫一下哦。

正向代理與反向代理

好了,接下來是另外兩個概念,正向代理與反向代理。

正向代理

這個太好解釋了,碼農們都喜歡用 Google 吧,因為一些眾所周知的原因,我們沒法直接訪問,因此,大家也都會找一些工具方法來訪問一些不可說的網站。在這種情況下,是需要下載一些軟件,或者配置一些東西,讓我們的瀏覽器通過代理,將請求先發(fā)送到一個外部服務器,然后由它再轉發(fā)請求到目的站點,這個過程就是正向代理。另外,還有一些游戲加速器,以及我們做開發(fā)經常會用到的 Fiddler 以及 Charles 抓包工具,這些也都是正向代理軟件。

簡單來說,正向代理需要我們客戶端去配置東西,或者使用軟件,將請求發(fā)送到指定的地方。

比如說,我們現在通過瀏覽器請求 Google 的網址,代理軟件攔截請求,然后發(fā)送到代理服務器。代理服務器接收到后,再將請求發(fā)送到真實的 Google 的服務器,處理完成后, Google 返回的響應發(fā)送回代理服務器,代理服務器再將請求返回給客戶端。

這就是正向代理,另外還有一種透明代理,意思就是這個代理服務器像是透明的一樣,只轉發(fā),不做別的事情,就和我們正常訪問目標網址一樣。

一句話,控制權在用戶,安裝啟用了代理就走代理,不裝不用不會走代理。

反向代理

說完正向的,反向的就好理解了,它和正向代理就是反過來的嘛。不需要我們在客戶端配置或者下載什么軟件,訪問的地址還是原來那個,只不過服務器上將我們的請求又轉發(fā)給了別的服務器。這個過程對于我們這些用戶是無感知的。

反向代理不需要在客戶端裝軟件,是由網站來控制用戶看到的內容。假如我的網站,www.zyblog.com.cn ,通過反向代理到了 Google ,那么大家訪問我的這個網址,實際上打開的會是 Google 的頁面。但是說實話,中文搜索分詞百度還是有優(yōu)勢的,哪天一高興,我再將我的網站反向代理到 Baidu ,那么用戶不需要換別的網址,還是繼續(xù)訪問 www.zyblog.com.cn ,看到的就會是百度的內容。

一句話,控制權在站長,不在用戶,用戶訪問的地址不變,但是會顯示什么,需要代理到哪里,是后端人員控制的。

再拿實際的業(yè)務來說,很多門戶網站其實是會把一些頻道外包的,比如說體育、健康頻道,它們的記者和資源其實也是有限的。一些小的頻道或者不是熱門的頻道就直接讓第三方公司來做。這時候,有一種方案是直接使用二級域名指到合作公司的服務器上,而另一種方案,不改變域名,直接將某個路徑,比如 /sports/ 這樣的反向代理到合作公司指定的地址路徑上就可以了。這是很常見的一種業(yè)務需求。

而大家做為碼農,接觸到的更多的業(yè)務需求,則是用于負載均衡以及后端程序的代理。負載均衡的問題我們后面講服務器組的時候再說,先來說說后端程序的問題。

因為我是 Java/.NET 出身,工作一年之后才轉的 PHP ,所以對前面兩種語言還是略有了解。除了它們之外,現在的 Go 語言以及經典的 C/C++ 這些編譯型語言,都是需要編譯之后才能運行的。它們并不像 PHP 一樣可以通過 FastCGI 直接運行。而且大部分情況下,它們運行后都會直接啟動一個服務,比如說直接運行 jar 包或者直接運行 go 編譯文件。這時,一般會啟動一個端口,通過這個端口就可以訪問服務。

通常來說,你要是直接在代碼中把端口設置成 80 ,那么其實這些程序也可以對外服務的。但是,這些動態(tài)服務程序普遍對靜態(tài)資源的處理都很差,而且,也不太靈活,比如說我在一臺服務器上要啟動多個應用,也沒辦法同時使用 80 端口。因此,大部分情況下,它們也會借助 Nginx 的反向代理來實現服務的部署。比如說,我們用 Java 啟動了三個程序,分別使用 8080、8081、8082 三個端口,然后在 Nginx 中,直接反向代理,通過不同的 location 路徑,使用統(tǒng)一的一個 80 端口對外服務就好了。

proxy_pass

Nginx 中,代理模塊是一個非常重要的模塊,全稱是 ngx_http_proxy_module ,是非常大也非常重要的一個模塊。其實在之前講 FastCGI 時就講過,它也是個代理模塊,只不過是通過 FastCGI 協(xié)議代理的。而 Proxy 模塊則是通用代理,使用 http 或 https 協(xié)議就可以,在 HTTP 模塊中的 Proxy 是七層負載的代理協(xié)議,Nginx 現在也有四層負載的 Stream 模塊,它里面也有一個代理子模塊,可以做四層負載均衡。

好了,點題一下,其實要配置一個反向代理,使用一個 proxy_pass 配置指令就可以了。就這么簡單,我們先來看它的介紹,后面再進行演示。這個指令只能配置在 location 以及帶條件判斷的 location 和 limit_except 下面,一般來說,就是 location 為主啦。

這個配置指令的作用就是設置代理服務器的協(xié)議和地址以及位置應映射到的可選 URI。作為協(xié)議,可以指定“http”或“https”。地址可以指定為域名或 IP 地址,以及可選的端口:

proxy_pass http://localhost:8000/uri/;

或作為在單詞“unix”之后指定并用冒號括起來的 UNIX 域套接字路徑:

proxy_pass http://unix:/tmp/backend.socket:/uri/;

如果一個域名解析為多個地址,則所有這些地址都將以循環(huán)方式使用。此外,可以將地址指定為服務器組。

參數值可以包含變量。在這種情況下,如果將地址指定為域名,則在所描述的服務器組中搜索該名稱,如果未找到,則使用解析器確定該名稱。

注意,這里比較重要。請求 URI 被傳遞給服務器,如下所示:

  • 如果 proxy_pass 指令是用一個 URI 指定的,那么當一個請求被傳遞到服務器時,與該位置匹配的規(guī)范化請求 URI 的部分將被指令中指定的 URI 替換:

    location /name/ {
        proxy_pass http://127.0.0.1/remote/;
    }
  • 如果 proxy_pass 沒有指定 URI,則請求 URI 以與處理原始請求時客戶端發(fā)送的相同格式傳遞給服務器,或者在處理更改的 URI 時傳遞完整的規(guī)范化請求 URI:在版本 1.1.12 之前,如果指定 proxy_pass 時沒有 URI,則在某些情況下可能會傳遞原始請求 URI 而不是更改后的 URI。

location /some/path/ {
    proxy_pass http://127.0.0.1;
}

在某些情況下,無法確定要替換的請求 URI 部分:

  • 當使用正則表達式指定位置時,以及在命名位置內。在這些情況下,應指定不帶 URI 的 proxy_pass。如果指定了 URI ,那么需要帶正則參數的形式,并且 Get 參數會有問題,我們后面的測試會使用這種形式,需要手動傳遞 $args 變量。

  • 當使用 rewrite 指令在代理位置內更改 URI 時,將使用相同的配置來處理請求(中斷):

    location /name/ {
        rewrite    /name/([^/]+) /users?name=$1 break;
        proxy_pass http://127.0.0.1;
    }

在這種情況下,指令中指定的 URI 將被忽略,并將完整更改的請求 URI 傳遞給服務器。

  • 在 proxy_pass 中使用變量時:

    location /name/ {
        proxy_pass http://127.0.0.1$request_uri;
    }

    在這種情況下,如果在指令中指定了 URI,它將按原樣傳遞給服務器,替換原始請求 URI。

WebSocket 代理需要特殊配置,并且從 1.3.13 版本開始支持。

上面的官方文檔的內容中,最后關于 URI 的部分比較重要,需要詳細看一下。接下來,我們就自己配置一下試試。

配置一個反向代理

首先,咱們配置一個 Server 吧,監(jiān)聽 8027 端口,然后反向代理到本機的 80 端口,這是最簡單的配置,就是本機之間不同端口的配置。

server {
  listen 8027;
  access_log logs/27.log;
  
  root html;
  location / {
   proxy_pass http://192.168.56.88/;
  }
}

或者,這樣寫也可以,反正是本機代理嘛。

proxy_pass http://127.0.0.1;

直接使用 localhost 也是可以的。你可以訪問一個 PHP 頁面,然后打印 $_SERVER 信息,可以看到 [SERVER_PORT] => 80 這樣的內容,PHP 接收到的端口號是 80 ,獲得的是反向代理轉發(fā)時請求的端口號。REMOTE_ADDR 信息也會跟著我們不同的設置產生變動。

反向代理到外網

將 proxy_pass 改成一個外網地址就可以了。

proxy_pass http://www.sina.com.cn/;

現在打開 http://192.168.56.88:8027/ 就會顯示新浪的頁面。

負載均衡反向代理

上面測試了本機和外網,內網其它主機也是可以的,我們可以復制一臺虛擬機,然后設置 IP 為 192.168.56.89 ,部署好 Nginx 應用,并且準備一個 index.html 和一個 1.php 文件。注意這兩個文件要與 88 主機上的內容不同,這樣才方便一會我們的測試。

先來試試直接代理到 89 上。

proxy_pass http://192.168.56.89;

訪問之后可以正常打開 89 主機上相關的內容。然后我們就來測試下負載均衡,需要在 http 模塊下配置一個 upstream 。

upstream proxy1 {
  server 192.168.56.88:80;
  server 192.168.56.89;
}

這個配置我們后面再學,現在你只要知道,它第一個參數是服務器組的名字,后面花括號內部的通過 server 指定多臺服務器,形成一個服務器組。默認的均衡策略是輪詢,也就是請求第一次走 88 的 80 端口,第二次再請求走 89 ,不寫端口號默認也是 80 端口。

然后直接 proxy_pass 代理指向這個服務器組就好了。

proxy_pass http://proxy1;

現在再次訪問,就會發(fā)現每次刷新,都會在 88 和 89 不同的頁面之間切換。這就是最簡單的負載均衡配置了。如果我們訪問一個 88 存在,而 89 不存在的頁面,那么就會一下正常,一下 404 。其它 500 之類的錯誤也是類似的,這里也可以解決掉錯誤頁面出現的情況,后面學習代理模塊的錯誤處理時會說。

URI 和正則問題

上面的配置是在 / 這個全局 URI 下配置的。如果是指定 URI ,比如這樣:

location /aaa/ {
 proxy_pass http://192.168.56.88;
}

那么實際請求的后端服務地址是 http://192.168.56.88/aaa/ ,Proxy 模塊會自動拼接 URI 及請求 GET 參數。而如果我們在 proxy_pass 中指定了 URI ,則會直接使用 praxy_pass 的。

location /aaa/ {
 proxy_pass http://192.168.56.89/a/;
}

這個配置最終請求后端的地址是 http://192.168.56.89/a/ 。

而如果是正則,在上面的官方文檔中也說明了,正則,同時在 proxy_pass 也指定了 URI 的話,因為無法確定需要轉發(fā)的內容,所以無法正常配置。

location ~ /bbb(.*) {
  proxy_pass http://192.168.56.88/aaa/;
}

檢查或者重載配置,會報出一個錯誤信息。

nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /etc/nginx/article.http.d/27.conf:37

那么要怎么處理呢?上面文檔也說了,必須要帶正則參數。比如這樣:

location ~ /bbb(.*) {
  proxy_pass http://192.168.56.88/aaa/?$1;
}

就可以正常通過了,如果只是普通正則,沒有 (.*) 內容也沒事,只要帶上一個 $1 就行,沒有括號匹配內容這個值就是空的。另外需要注意的是,這種形式代理轉發(fā)過來的,不會帶 GET 參數,因此,可以這么寫:

location ~ /bbb(.*) {
  proxy_pass http://192.168.56.88/aaa/?$args&$1;
}

現在嘗試訪問 http://192.168.56.88:8027/bbb/sdf?lksj 這個路徑,最終請求的代理服務器的路徑是 http://192.168.56.88/aaa/?lksj&/sdf 這樣的內容。

配置一個正向代理

說了半天反向代理,那么 Nginx 能做正向代理嗎?既然都寫在這里了,那肯定是可以的呀。

server {
  listen 8027;
  access_log logs/27.log;
  resolver 114.114.114.114;
  location / {
   proxy_pass $scheme://$host$request_uri;
 }
}

首先需要配置一個 resolver 也就是 DNS 解析服務器的地址,咱們就通用的 114 就好了。這個指令之前在基礎的 HTTP 核心模塊的學習中就學過,當時也說過它是在做正向代理的時候需要用到的。原因嘛,因為正向代理,我們接收到的請求都是域名,需要有 DNS 解析到真實的 IP ,不像反向代理,是通過 Nginx 發(fā)送請求,這里請求是直接轉發(fā)的,沒有調用其它發(fā)送請求的函數。因此,需要有這個配置,如果不配置它的話,訪問會報出 502 錯誤,日志中會有如下記錄。

2022/09/06 10:58:21 [error] 1615#0: *130 no resolver defined to resolve www.baidu.com, client: 192.168.56.1, server: , request: "GET http://www.baidu.com/ HTTP/1.1", host: "www.baidu.com"

然后就是 proxy_pass 的配置。這里我們全部都是使用變量,因為我們要訪問的是用戶在客戶端輸入的網址,這些內容需要通過變量獲取到。就像上面在概念中說的,正向代理要訪問誰,是用戶決定的,我們做代理時,要拿到用戶請求的網址信息。

接下來,通過瀏覽器進行代理配置,所有瀏覽器都可以配置,這里我就直接拿 Postman 配置,在設置中打開下面的代理并填上代理服務器的 IP 地址和端口。

試著用配好代理的這個瀏覽器訪問一下百度吧,正常打開是不是?但是,查看 88 服務器上 Nginx 的 access_log 日志,你會發(fā)現這是通過我們的 Nginx 代理請求的。

192.168.56.1 - - [15/Sep/2022:11:09:18 +0800] "GET http://www.baidu.com/ HTTP/1.1" 200 89726 "-" "PostmanRuntime/7.29.2" "-"

使用 WireShark 抓包也能看出來。

總結

今天的內容很多都是概念,包括代理、正向代理、反向代理,還接觸到了一點負載均衡的概念。也說明了即使不用負載均衡,很多情況下我們也需要代理的原因。而真正學習到的配置指令就只有一個 proxy_pass 。是的,就這么簡單,一個代理服務器就配置完成了。不過僅有這個還不夠,整個代理模塊還有很多其它的配置選項,我們在后面還會一一學習。不過大家不用太擔心,因為我們已經學習過 FastCGI 了,整個 Nginx 只要是帶 proxy 這個單詞的,不管是 FastCGI、SCGI還是UWSGI ,或是我們現在要學的普通代理,大部分配置指令都是相通的。因此,后面的學習還是比較輕松愉快的。不過還是強調一下,SCGI、UWSGI 這兩個模塊我們就不單獨講了哦,一是太像了,二是咱們 PHP 碼農大部分情況下用不到,主攻 FastCGI 和 Proxy 就可以啦。

參考文檔:

http:///en/docs/http/ngx_http_proxy_module.html

    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多