Nginx 筆記 - Reverse Proxy 與負載平衡
什麼是 Proxy?
Proxy(代理)是一個位於客戶端和伺服器之間的中間服務器,它接收來自客戶端的請求,並將這些請求轉發到伺服器。代理在客戶端和伺服器之間充當了一個中繼角色,並提供了幾個關鍵功能:
- 隱藏客戶端的身份:代理可以隱藏客戶端的身份和位置,讓伺服器只能看到代理伺服器。這可以保護客戶端的隱私和安全,防止客戶端的真實身份和位置被暴露給伺服器或其他第三方。
- 優化網絡流量:代理可以緩存網絡資源,從而減輕伺服器的負載,提高網絡效能。
- 過濾和監控網絡流量:代理可以根據設定的規則對網絡流量進行過濾和監控,從而實現網絡安全和管理控制。
一些日常生活中常見的 Proxy 使用案例如下:
- 網際網路服務提供商(ISP):台灣的主要 ISP(網際網路服務提供商),例如:中華電信、遠傳電信、台灣大寬頻等供應商使用 Proxy 來提供網絡連接服務。透過 ISP 的 Proxy,用戶的網絡流量可以通過代理伺服器進行路由、過濾和監控。這可以幫助 ISP 控制和優化網絡流量,同時提供更安全的網絡體驗。
- 企業/校園網絡:許多企業或是學校會使用 Proxy 來管理和監控內部網絡流量。透過企業的 Proxy,IT 管理員可以
實施安全政策、過濾不安全或不恰當的內容、限制網絡訪問,並提供更高效的網絡連接。 - 緩存服務:Proxy 可以用於緩存常見的網絡資源,例如圖片、CSS 和 JavaScript 檔案等。這樣一來,當用戶請求相同的資源時,代理可以直接提供本地緩存的副本,節省帶寬和加快網頁載入速度。
什麼是 Reverse Proxy (反向代理)?
Reverse Proxy(反向代理)是代理的一種形式,它同樣也位於伺服器和客戶端之間,將客戶端的請求轉發到一組後端伺服器。與傳統的正向代理不同,反向代理將客戶端的請求轉發到多個伺服器,並根據某些規則(如負載均衡)來選擇最適合的伺服器來處理請求。
- 負載均衡:反向代理可以將流量分散到多個後端伺服器,從而平衡伺服器的負載,提高整體性能和可靠性。
- 高可用性:通過將流量分散到多個後端伺服器,反向代理可以實現故障轉移和故障恢復,確保在某個伺服器失效時網站仍然可用。
- 安全性:反向代理可以作為安全屏障,保護後端伺服器免受直接攻擊。它可以過濾惡意請求。
Proxy vs Reverse Proxy
當談到 Proxy 和 Reverse Proxy 時,它們的最大不同點在於它們的工作方式和適用場景:
| Proxy(正向代理) | Reverse Proxy(反向代理) | |
|---|---|---|
| 用途 | 可以將客戶端請求路由到目標伺服器 | 負載平衡/緩存等用途,接收客戶端請求並轉發到內部伺服器 |
| 方向 | 代表客戶端進行請求,然後將請求轉發到目標伺服器 | 代表目標伺服器接收請求,然後將請求轉發到適當的內部伺服器 |
| 配置 | 客戶端必須明確指定代理伺服器 | 只需對 Reverse Proxy 發送請求即可 |
| 隱私 | 客戶端知道目標伺服器位置,但目標伺服器無法得知客戶端位置 | 客戶端無法得知目標伺服器的位置,只知道 Reverse Proxy 的位置 |
Proxy 主要用於保護客戶端的隱私和安全,而 Reverse Proxy 則用於提高伺服器端的效能和可靠性。它們在工作方式、用途和配置位置等方面存在明顯的差異。
Canary Deployment(金絲雀部署)和 Reverse Proxy(反向代理)
Canary Deployment通常涉及將新版本的應用程式或服務逐步引入生產環境,僅讓一小部分的流量或用戶流向新版本,而大部分流量仍然導向舊版本。這樣可以在生產環境中進行測試和驗證新版本的穩定性和性能,同時降低了對整個系統的影響。在Canary Deployment中,Reverse Proxy 扮演著重要的角色。它接收用戶的請求並根據特定的規則將請求轉發到適當的後端伺服器。
透過Reverse Proxy,可以實現Canary Deployment的以下功能:
- 路由控制:Reverse Proxy可以根據特定的路由規則將一部分用戶流量導向新版本的應用程式,而將其他用戶流量仍然導向舊版本。這樣可以實現Canary Deployment的階段性部署,並逐步增加新版本的用戶數量。
- 負載平衡:Reverse Proxy可以在多個後端伺服器之間均勻分配用戶流量。在Canary Deployment中,Reverse Proxy可以根據設定的權重將一部分用戶流量引導到新版本的後端伺服器,以評估新版本的性能和穩定性。
- 監控和恢復:Reverse Proxy可以提供監控和日誌記錄功能,用於收集新版本應用程式的監控數據和日誌。如果新版本出現問題或不符合預期,可以通過Reverse Proxy迅速切換回舊版本,以確保系統的穩定性和可用性。
為什麼叫 Canary(金絲雀)部署?? 在過去的時代,煤礦工人會攜帶一隻小型金絲雀進入煤礦中。金絲雀對有毒氣體特別敏感,當氣體濃度達到危險水平時,金絲雀就會首先出現不適甚至死亡,警示礦工們及時撤離以免受害 (金絲雀 QAQ)。
客戶端發送 Request 給 Nginx (反向代理)時
當使用者在瀏覽器底下根據 HTTPS 對一個 Nginx Server 發出請求時,倘若 Nginx 是一個作為反向代理的伺服器,請求的過程大致上如下:
- 客戶端對 Nginx 發送 HTTP/HTTPS Request。
- Nginx 創建一個新的 TCP 連接與客戶端進行通信。
- 如果使用 HTTPS,客戶端和 Nginx 之間的 TCP 連接將進行 TLS/SSL 握手並交換密鑰進行加密。
- Nginx 解析 Request ,並根據其配置進行反向代理,將 Request 轉發給後端伺服器。
- Nginx 和後端伺服器之間建立一個新的 TCP 連接。
- Nginx 將 Request 轉發給後端伺服器。
- 後端伺服器處理 Request ,並將 Response 發送回 Nginx。
- Nginx 接收到 Response ,使用先前建立的 TCP 連接將 Response 轉發回客戶端。
- 如果使用 HTTPS,Nginx 會將 Response 加密並通過 TLS 連接發送回客戶端。
當客戶端在 https 協議下對一個 Nginx (reverse proxy server) 發出 Request 時,客戶與 Nginx 之間需要建立 TCP 連線。一旦 TCP 連線建立完成後,客戶端和 Nginx 之間的 TCP 連接將進行 TLS/SSL 握手並交換密鑰進行加密,客戶就會將 HTTP request 發送到 Nginx。Nginx 接收 request 後需要進行解密並解析出 Request 的內容,並根據設定的規則進行重寫 URL、靜態資源緩存,然後進行負載平衡與反向代理,決定轉發到哪個 Backend server,再建立 TCP 連接到 Backend server,轉發 Request ,並等待 Backend server 的 Response 。一旦收到 Response ,Nginx 會將 Response 重新傳送給客戶端。由於這個過程涉及到解密加密、解析 Request 、負載平衡、TCP 連接等複雜的操作,因此會消耗大量的 CPU 資源和記憶體,尤其是當有大量的客戶端發送 Request 時,Nginx 很容易變得過載。
Reverse Proxy Load Balancers
在 Nginx 中,有幾種可用的負載均衡方法,可以根據需要選擇最適合的方法。下面是三種常見的負載均衡方法:
- round-robin(輪詢) : round-robin 是一種最常見的負載均衡方法,也是 nginx 的預設值。它將請求按照順序分發到可用的伺服器。當有多個伺服器時,每個連續的請求都會被分發到下一個伺服器,直到再次從頭開始。這種方法確保了每個伺服器在相同的請求量下都能接收到相似的流量。
- ip_hash: ip_hash 方法根據 client 端的 IP Address 進行分發。每個客戶端的 IP 地址都會被 hash,然後根據 hash value 將請求分發到對應的伺服器。這樣做的好處是,當同一個 client 端發送多個請求時,它們將始終被分發到同一個伺服器,從而確保 session 的一致性。這對於需要保持特定狀態或 session 的應用程式相當重要。
- least_conn(最少連接): least_conn 方法會根據當前的連接數量來選擇具有最少連接數的伺服器。當請求到達時,Nginx 將根據伺服器的當前連接數量選擇一個具有最少連接的伺服器來處理該請求。這種方法有助於在伺服器之間均衡分配負載,並確保連接數盡可能均勻。
這些負載均衡方法可在 Nginx 的配置中使用 upstream 指令來定義。例如: