NGINX 反向代理


代理與反向代理

假設網絡上有三台機器:

  • X:你的電腦
  • Y:代理服務器
  • Z:網站

通常,你會直接訪問需要的網絡資源,此時路徑是由你的電腦直接到網站 X->Z。

代理(Proxy)

但某些情況下,X 並不能直接訪問到 Z。原因可能是兩方面的,

  • X 所在的網絡將 Z 進行了屏蔽封鎖,比如公司內網禁用一些娛樂性質的網站,防止員工工作時間娛樂。
  • Z 將 X 進行了屏蔽。比如 Z 發現來自 X 的請求異常,懷疑是惡意攻擊,所以將 X 的 IP 封掉。

此時 Y 在中間可充當 X 的代理,將 X 的請求轉發到 Z,拿到內容后再返回給 X。此時路徑為 X->Y->Z。

也就是說,代理是 X 端主動配置和發起的,X 明確知道 Y 並不是返回內容的服務器。

反向代理 (Reverse Proxy)

某些情況下,Z 不想讓 X 直接訪問,所以配置一個 Y 在前面充當代理提供服務。

此時,作為用戶訪問的是 Y,並不知道 Z 才是真正提供服務的機器,用戶代理了,相比前面,所以這里是 反向代理。

反向代理下,Z 在后台對外不公開只內網可訪問,而作為反向代理的 Y 對外公開可通過公網訪問。

反向代理的場景:

  • 比如 Z 是個大型網站,請求量巨大,單台機器是無法滿足所有請求的,所以同樣的網站內容部署在了多台機器上。然后配置一台反向代理的機器,將請求再就近轉發到某台機器。比如 CDN。
  • 負載均衡。將請求平均分配到各機器,以至於不會讓某些機器過載,同時將掛掉的機器其請求轉發到還在正常運行的機器上。

NGINX 中反向代理的配置

請求轉發

通過 proxy_pass 可將請求直接轉發。

location /some/path/ {
    proxy_pass http://www.example.com/link/;
}

目標地址中的 path 部分會替換掉 location 參數中對應位置中的 path。比如這里 /some/path/page.html 會被轉發到 http://www.example.com/link/page.html

其中目標地址可以是 IP,或帶端口,

location ~ \.php {
    proxy_pass http://127.0.0.1:8000;
}

除了轉發到 HTTP 服務器,還支持其他類型協議的轉發,相應的指令為:

請求頭的轉發

默認情況下 NGINX 為代理的請求設置上了兩個請求頭,Host 設置成 $proxy_host 變量的值,Connection 設置為 close。其他值為空的請求頭會去掉。通過 proxy_set_header 指令可修改代理時的請求頭。

location /some/path/ {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass http://localhost:8000;
}

代理時如果想禁止某個頭部的傳遞,直接將其設置為空即可,

location /some/path/ {
    proxy_set_header Accept-Encoding "";
    proxy_pass http://localhost:8000;
}

Buffer 的設置

作為代理,在拿到完整響應前將結果暫存在內部的 buffer 數據中,拿到完整響應后再將結果返回到客戶端。這種將響應暫存的方式可提高代理的效率,而同步的方式會浪費代理服務器的資源。

默認 buffer 模式為開啟狀態,可通過 proxy_buffering 進行開關。

proxy_buffers 控制單個請求為其分配的 buffer 大小和數量。

location /some/path/ {
    proxy_buffers 16 4k;
    proxy_buffer_size 2k;
    proxy_pass http://localhost:8000;
}

關閉某些 location 下的 buffer 設置:

location /some/path/ {
    proxy_buffering off;
    proxy_pass http://localhost:8000;
}

出口地址

通過 proxy_bind 指令可配置代理服務器的出口地址,然后配置內部機器只接收來自該出口地址的請求。

location /app1/ {
    proxy_bind 127.0.0.1;
    proxy_pass http://example.com/app1/;
}

location /app2/ {
proxy_bind 127.0.0.2;
proxy_pass http://example.com/app2/;
}

IP 地址也可指定為變量,比如 $server_addr 為接收請求機器的 IP。

location /app3/ {
    proxy_bind $server_addr;
    proxy_pass http://example.com/app3/;
}

相關資源


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM