負載平衡 (Load Balancing)
為什麼需要負載平衡?
水平擴展(加更多伺服器)需要告訴客戶端「要跟哪台伺服器溝通」,這就是負載平衡的核心任務。
客戶端負載平衡
客戶端自己決定要連哪台伺服器(透過服務登錄中心或 DNS)。
| 例子 | 機制 |
|---|---|
| Redis Cluster | 客戶端雜湊 key 決定目標節點,錯誤節點回 MOVED 指引 |
| DNS 輪換 | DNS 回傳輪換過的 IP 列表,客戶端依序嘗試 |
優點:無需額外網路跳點,延遲最低
缺點:客戶端需定期更新伺服器列表,更新有延遲
何時用客戶端 LB
(1) 少量可控制的客戶端(內部微服務、gRPC 客戶端)
(2) 大量客戶端但可容忍緩慢更新(DNS)
專用負載平衡器
位於客戶端和後端之間的獨立元件,每個請求多一跳,換取細粒度控制。
L4 負載平衡器(傳輸層)
Client ──TCP連線──► L4 LB ──TCP連線──► Server
(維護持久 TCP 連線)
- 根據 IP/Port 路由,不理解 HTTP 內容
- 維護持久 TCP 連線(同一 session 的請求到同一台 server)
- 速度快、CPU 消耗低
WebSocket 必須用 L4
L7 LB 終止傳入連線再建立新連線,會破壞 WebSocket 的持久連線。
WebSocket 必須使用 L4 LB 維護端到端的 TCP 連線。
L7 負載平衡器(應用層)
Client ──HTTP請求──► L7 LB ──轉發HTTP──► Server
(理解HTTP內容,智慧路由)
- 理解 HTTP,可根據 URL、headers、cookies 路由
- 終止傳入連線,向後端建立新連線
- CPU 消耗更高,功能更靈活
L7 LB 典型功能:
/api/*路由到 API 伺服器,/static/*路由到靜態檔案伺服器- 根據 cookie 確保同一用戶到同一台伺服器(Session Affinity)
面試預設選 L7
除 WebSocket 外的所有 HTTP 流量,預設用 L7 LB。
負載平衡演算法
| 演算法 | 機制 | 適合場景 |
|---|---|---|
| 輪詢(Round Robin) | 依序分配 | 無狀態服務、通用 |
| 隨機(Random) | 隨機選擇 | 無狀態服務 |
| 最少連線(Least Connections) | 發到連線數最少的伺服器 | 持久連線服務(SSE、WebSocket) |
| 最快回應(Least Response Time) | 發到回應最快的伺服器 | 延遲敏感服務 |
| IP 雜湊(IP Hash) | 由客戶端 IP 決定 | Session 持久性需求 |
持久連線服務的 LB 陷阱
SSE/WebSocket 等長連線如果用 Round Robin,新加入的伺服器不會分到已建立的連線,舊伺服器會逐漸積累所有連線。
持久連線服務必須用 Least Connections。
健康檢查
LB 自動監控後端伺服器,故障時停止路由:
| 類型 | 方式 | 成本 |
|---|---|---|
| TCP 健康檢查 | 檢查是否接受新連線 | 低 |
| L7 健康檢查 | 發 HTTP 請求確認 200 回應 | 稍高 |
這是負載平衡器對高可用性至關重要的原因——自動偵測故障並繞道,無需人工介入。
降低全球延遲
CDN(內容傳遞網路)
全球分佈的邊緣伺服器網路,快取靜態內容(圖片、影片、JS/CSS)。
無 CDN: 用戶(台北) ──80ms──► 伺服器(紐約)
有 CDN: 用戶(台北) ──5ms───► 邊緣節點(台北)
適合:可快取性高、需要全球查詢的資料(靜態資源、公開 API 回應)
區域分片(Regional Partitioning)
按地理區域分片資料,讓每個區域只處理相關資料。
Uber 例子:
- 美東區域(資料中心在紐約)← 處理美東的叫車請求
- 美西區域(資料中心在洛杉磯)← 處理美西的叫車請求
- 台北用戶永遠不會叫到紐約的司機 → 跨區查詢不必要
伺服器和資料庫共址(co-located),查詢延遲最低。
Related Notes
- 01-Networking/02-TCP-vs-UDP — L4 LB 處理 TCP 層
- 01-Networking/05-Realtime-Protocols — WebSocket 需要 L4 LB
- 01-Networking/04-API-Paradigms — L7 LB 可做 API 路由
- 01-Networking/07-Fault-Handling — 健康檢查 + 容錯的延伸
- 01-Networking/Practice-Networking