反向代理 vs 負載平衡器:何時該用哪一種?Nginx 實戰解析
你可能經常聽到「反向代理」和「負載平衡器」這兩個詞被混用。但在設定 Nginx 時,了解它們的差異至關重要——這會影響你如何架構基礎設施、處理 SSL,以及擴展應用程式。
本指南將釐清這些困惑。你將了解兩者各自的功能、何時該使用哪一種,以及如何在 Nginx 中以清晰實用的範例進行設定。
什麼是反向代理?
反向代理位於客戶端和你的後端伺服器之間。它接收客戶端請求,將其轉發到適當的後端,然後回傳回應。客戶端永遠不會直接與你的後端通訊。
常見用途:
- SSL 終止:在代理層處理 HTTPS,讓後端只需處理 HTTP。
- 快取:儲存靜態資源或 API 回應,以減輕後端負載。
- 安全性:隱藏後端細節、過濾請求,並緩解 DDoS 攻擊。
- 壓縮:在傳送給客戶端之前,對回應進行 Gzip 或 Brotli 壓縮。
Nginx 常被用作應用程式伺服器(如 Node.js、Python(Gunicorn/uWSGI)或 Java(Tomcat))前方的反向代理。
什麼是負載平衡器?
負載平衡器將傳入流量分散到多個後端伺服器。其主要目標是提升可用性、可擴展性和容錯能力。
主要功能:
- 流量分配:使用輪詢(round-robin)、最少連線(least connections)或 IP 雜湊(IP hash)等演算法來分散請求。
- 健康檢查:自動停止將流量傳送到不健康的伺服器。
- 工作階段持續性:在需要時將使用者保持在同一個後端。
負載平衡器可以是硬體(F5、Citrix)或軟體(Nginx、HAProxy、雲端 LB)。Nginx 的 upstream 模組使其成為一個功能強大的軟體負載平衡器。
反向代理 vs 負載平衡器:關鍵差異
| 面向 | 反向代理 | 負載平衡器 |
|---|---|---|
| 主要目的 | 轉發請求,增加功能(SSL、快取) | 將負載分散到多個伺服器 |
| 後端數量 | 通常一個(或少數幾個) | 多個,通常很多 |
| 重點 | 功能性、安全性、效能 | 可擴展性、高可用性 |
| 健康檢查 | 選用 | 必要 |
實際上,負載平衡器是一種特化的反向代理。許多工具(包括 Nginx)可以同時執行兩者。
何時使用反向代理
當你需要以下情況時,請使用反向代理:
- 服務單一後端伺服器,但想要 SSL、快取或壓縮。
- 在同一 IP 後方,以不同路徑或子網域託管多個應用程式。
- 透過不直接暴露後端,增加額外的安全層。
範例:一個執行在 3000 埠的 Node.js API,由 Nginx 處理 HTTPS 並提供靜態檔案。
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/nginx/ssl/api.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/api.example.com.key;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
何時使用負載平衡器
當你有以下情況時,請使用負載平衡器:
- 多個後端伺服器來處理高流量。
- 需要高可用性——如果一台伺服器故障,其他伺服器可以接手。
- 滾動部署或藍綠部署。
範例:三個 Node.js 實例在 Nginx 後方,使用輪詢(round-robin)。
upstream backend {
server 10.0.0.1:3000;
server 10.0.0.2:3000;
server 10.0.0.3:3000;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Nginx 會平均分散請求。你可以新增健康檢查和其他參數來微調行為。
在 Nginx 中結合兩種角色
大多數實際部署會將 Nginx 同時用作反向代理和負載平衡器。例如:
upstream app_servers {
least_conn;
server 10.0.0.1:3000 max_fails=3 fail_timeout=30s;
server 10.0.0.2:3000 max_fails=3 fail_timeout=30s;
server 10.0.0.3:3000 backup;
}
server {
listen 443 ssl;
server_name app.example.com;
ssl_certificate /etc/nginx/ssl/app.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/app.example.com.key;
location /static/ {
root /var/www/static;
expires 30d;
}
location / {
proxy_pass http://app_servers;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
在這裡,Nginx 終止 SSL、提供靜態檔案,並透過健康檢查在三台應用程式伺服器之間進行負載平衡。
Nginx 作為反向代理/負載平衡器的最佳實踐
- 設定適當的標頭:務必傳遞
Host、X-Real-IP和X-Forwarded-For,讓後端知道原始客戶端。 - 啟用 HTTP/2:在
listen指令中新增http2以獲得更好的效能。 - 調整緩衝區和逾時:根據應用程式行為調整
proxy_buffer_size、proxy_read_timeout。 - 使用健康檢查:Nginx 開源版有被動檢查;Nginx Plus 提供主動檢查。
- 明智地記錄日誌:使用自訂日誌格式來擷取上游回應時間,以便除錯。
分析 Nginx 日誌對於找出瓶頸至關重要。像 Nginx Log Analyzer 這樣的工具可以幫助你解析存取日誌,快速識別緩慢的上游或錯誤。
常見問題
Nginx 可以同時是反向代理和負載平衡器嗎?
可以。Nginx 可以終止 SSL、快取內容,並同時將請求分散到多個後端。upstream 區塊定義後端池,而 proxy_pass 指令負責轉發請求。
如果我只有一台後端伺服器,還需要負載平衡器嗎?
不一定。單獨的反向代理就能處理 SSL、快取和安全性。但新增具有多個後端的負載平衡器可提升可用性——如果一台伺服器故障,其他伺服器仍可提供服務。
Nginx 如何選擇要將請求傳送到哪個後端?
預設情況下,Nginx 使用輪詢(round-robin)。你可以使用 least_conn(最少連線)、ip_hash(基於客戶端 IP 的工作階段黏著)或 hash(自訂鍵值)等指令來變更。
準備好最佳化你的 Nginx 設定了嗎?從使用我們的免費 Nginx 日誌解析器分析日誌開始,找出效能問題並微調你的設定。