Skip to content

負載平衡與閘道器

🎯 核心問題

當單台伺服器扛不住時,如何把流量「聰明地」分配到多個伺服器執行個體? 負載平衡是現代分散式系統的「分發員」。本文透過真實案例(飲料店收銀、快遞分揀、交通指揮)深入理解負載平衡的設計哲學和工程實踐。


1. 為什麼要「負載平衡」?

1.1 從一個真實案例說起:某網站的架構演進

某創業公司在使用者量快速增長時遇到了嚴重的效能問題:

情境還原:

階段一:單台伺服器
使用者 → 伺服器(1 核 2G)

    日活 1000 → 活躍時間:1000 人同時存取

問題:CPU 100%,回應慢,經常當機

⚠️ 單台伺服器的致命問題

  • 效能瓶頸:CPU 100%,回應時間 > 5 秒
  • 單點故障:伺服器掛了,整個網站無法使用
  • 擴充困難:只能垂直升級(加 CPU、記憶體),貴且有限

改進後的架構(引入負載平衡):

階段二:多台伺服器 + 負載平衡
使用者 → 負載平衡器(Nginx)

     ├→ 伺服器 1(1 核 2G)
     ├→ 伺服器 2(1 核 2G)
     └→ 伺服器 3(1 核 2G)

✨ 改進後的效果

  • 效能提升:3 台伺服器並行處理,回應時間 < 1 秒
  • 高可用性:1 台伺服器掛了,其他伺服器繼續服務
  • 水平擴充:需要更多效能?加伺服器就行

1.2 負載平衡的生活化比喻

飲料店收銀台

想像你開了一家網紅飲料店:

  • 1 個收銀台:顧客排隊,後面的人等不及,負評
  • 3 個收銀台:員工分配顧客到不同收銀台,效率提升 3 倍

負載平衡就是「收銀台分配員」

  • 使用者(顧客) → 請求服務
  • 負載平衡器(分配員) → 把請求分配到不同伺服器
  • 伺服器(收銀台) → 處理請求
负载均衡器类型
从四层到七层,从硬件到软件的演进
传统架构单点
🖥️
Web Server
负载: 95% 🔥
负载均衡架构分布式
⚖️L4 Load Balancer
🖥️
S1
🖥️
S2
🖥️
S3
📦四层负载均衡 (L4)
工作原理

基于传输层信息(IP地址+端口)进行流量分发。不关心应用层内容,只做"快递分拣",因此性能极高。

典型产品
LVS (Linux Virtual Server)HAProxy (TCP模式)AWS NLBAzure Load Balancer
适用场景
  • 需要极高吞吐量的场景
  • TCP/UDP流量分发
  • 不需要内容识别的场景
  • 微服务间通信
性能对比一览
类型
处理层
性能
灵活性
成本
硬件负载均衡
L4/L7
$$$$$
四层负载均衡
L4 (传输层)
$$
七层负载均衡
L7 (应用层)
$$$
软件负载均衡
L4/L7
$

2. 什麼是負載平衡?

2.1 四層負載平衡(L4):只看門牌號碼

工作在傳輸層(TCP/UDP),就像快遞員只看你家的門牌號碼(IP 位址 + 連接埠號),不關心你家是做什麼的。

特點:

  • 速度超快:只做簡單的位址轉送,不解析資料封包內容
  • 適用情境:資料庫連線、Redis 快取、長連線遊戲伺服器
  • 代表產品:LVS(Linux Virtual Server)、AWS NLB、Azure Load Balancer
工作原理
用戶端請求 → L4 負載平衡器 → 後端伺服器

         只看 IP + Port

         快速轉送(不拆封包內容)

2.2 七層負載平衡(L7):檢查包裹內容

工作在應用層(HTTP/HTTPS),就像快遞員不僅看門牌號碼,還會打開包裹檢查內容,根據內容決定怎麼送。

特點:

  • 智慧路由:可以根據 URL 路徑、HTTP 標頭、Cookie 等做精細化路由
  • 進階功能:SSL 卸載、內容快取、壓縮、安全 WAF
  • 適用情境:Web 應用、API 閘道器、微服務架構
  • 代表產品:Nginx、HAProxy、AWS ALB、Envoy
工作原理
用戶端請求 → L7 負載平衡器 → 解析 HTTP 內容

         檢查 URL、Header、Cookie

         智慧路由到特定伺服器

2.3 L4 vs L7 對比一覽

維度四層負載平衡(L4)七層負載平衡(L7)
工作層級傳輸層(TCP/UDP)應用層(HTTP/HTTPS)
決策依據IP 位址 + 連接埠號URL、Header、Cookie、Body
處理速度極快(核心態處理)較快(使用者態解析)
功能豐富度基礎轉送SSL 卸載、快取、壓縮、WAF
典型情境資料庫、遊戲、長連線Web 應用、API 閘道器、微服務
代表產品LVS、AWS NLBNginx、HAProxy、AWS ALB

3. 核心問題一:如何避免「壞掉」的伺服器繼續接客?

3.1 健康檢查:別讓「生病」的伺服器拖累系統

想像一下,你的某個收銀台突然壞了,但分配員不知道,還在源源不絕地把顧客分過去。結果隊伍越來越長,顧客怨聲載道。

健康檢查(Health Check)就是防止這種情況發生的「哨兵」。它定期「體檢」每台伺服器,發現「生病」的立即從佇列中移除,等「康復」了再請回來。

3.2 主動健康檢查 vs 被動健康檢查

主動健康檢查(Active Health Check):負載平衡器主動「敲門」問伺服器「你還在嗎?」

  • 定期傳送探測請求(如 HTTP /health、TCP ping)
  • 回應逾時或傳回錯誤碼則認為不健康
  • 優點:檢測結果準確可靠
  • 缺點:產生額外的探測流量

被動健康檢查(Passive Health Check):負載平衡器「觀察」真實業務流量的回應情況

  • 統計實際請求的回應時間、錯誤率
  • 連續多次失敗則認為不健康
  • 優點:不產生額外流量
  • 缺點:需要足夠的流量樣本才能判定
閾值設定表
指標健康閾值不健康閾值說明
HTTP 狀態碼200-399400+ 或逾時4xx/5xx 都認為失敗
TCP 連線成功建立連線逾時檢查連接埠是否可達
回應時間< 500ms> 2000ms逾時時間通常設為 2-5 秒
連續失敗次數-3 次避免單次抖動誤判
檢查間隔-5s太頻繁會增加負載

💡 常見踩坑:閾值設定太「敏感」

某團隊將健康檢查的回應時間閾值設為 100ms,而他們的應用平均回應時間在 80-120ms 之間波動。結果是伺服器頻繁被標記為「不健康」,導致流量在健康和不健康之間反覆橫跳,系統整體可用率反而下降。

正確的做法:閾值應該設定為 P99 回應時間的 2-3 倍,給正常波動留出足夠的緩衝空間。


4. 核心問題二:如何保證「老顧客」一直找同一個「收銀員」?

4.1 工作階段保持:讓「老顧客」一直找同一個「收銀員」

想像你是飲料店的常客,每次來都由同一個店員接待。她知道你的口味偏好(半糖、去冰),服務起來又快又貼心。但如果每次來都換一個新人,你得一遍遍重複同樣的要求,效率大打折扣。

工作階段保持(Session Persistence / Sticky Session) 就是解決這個問題的方法:確保同一個使用者的請求,始終被路由到同一台後端伺服器。

会话保持机制
Cookie、IP哈希与粘性会话的技术对比
应用场景:
👤
用户A
👥
用户B
👨‍💼
用户C
请求
⚖️负载均衡器
🍪
Cookie 插入
通过HTTP Cookie保持会话
会话映射表
sess_abc123Server 1
sess_def456Server 2
sess_ghi789Server 1
🖥️
Server 1
10.0.1.10
选中
🖥️
Server 2
10.0.1.11
🖥️
Server 3
10.0.1.12
三种会话保持机制对比
🍪Cookie 插入
不受客户端IP变化影响
首次请求即可保持会话
客户端需支持Cookie
存在Cookie被禁用的风险
#️⃣IP Hash
无需客户端支持任何机制
无状态,LB重启不影响会话
客户端IP变化会丢失会话
难以做到真正的负载均衡
📝粘性会话
结合Cookie和IP两种方式优势
支持会话复制和故障转移
实现复杂,需要应用支持
会话复制带来性能开销

4.2 三種工作階段保持機制對比

機制實作原理優點缺點適用情境
Cookie 插入LB 在回應中插入 Cookie,後續請求攜帶此 Cookie不受 IP 變化影響,首次請求即可保持用戶端需支援 Cookie,可能被停用電商購物車、登入態保持
IP 雜湊對用戶端 IP 做雜湊計算,對應到特定伺服器無需用戶端支援,無狀態IP 變化會遺失工作階段,難以均勻分布無 Cookie 環境、WebSocket
黏性工作階段表LB 維護工作階段到伺服器的對應表支援工作階段複製和故障轉移佔用 LB 記憶體,需要額外同步高可用性要求嚴格的場景

💡 使用建議

  • Cookie 插入:優先推薦,相容性好
  • IP 雜湊:只用於 WebSocket 等特殊情境
  • 黏性工作階段表:配合 Cookie,提供故障轉移能力

5. 核心問題三:如何實現零停機部署?

5.1 藍綠部署:「一鍵切換」的零停機發布

核心思想:同時維護兩套完全相同的生產環境(藍環境和綠環境),但只有一個環境對外提供服務。

蓝绿部署
零停机发布的经典策略,两套环境瞬间切换
🔵
蓝环境
v1.0.0
100% 流量
🟢
绿环境
v1.1.0
0% 流量
用户流量
👤
👤
👤
👤
👤
⚖️
负载均衡器
当前指向: 🔵 蓝环境
🔵蓝环境v1.0.0
🖥️B1
🖥️B2
🖥️B3
🟢绿环境v1.1.0
🖥️G1
🖥️G2
🖥️G3
蓝绿部署流程
1
绿环境部署
在绿环境部署新版本,进行冒烟测试
2
切换流量
将负载均衡器指向绿环境,流量瞬间切换
3
监控观察
观察绿环境运行状态,确认无异常
4
蓝环境升级
在蓝环境部署新版本,为下次切换做准备
蓝绿部署优缺点
优点
  • 零停机时间:流量切换在毫秒级完成,用户无感知
  • 快速回滚:发现问题可立即切回原环境,风险可控
  • 完整的预发布测试:新环境可完整测试后再接管流量
  • 数据一致性:无需处理新旧版本同时运行时的兼容问题
缺点
  • 资源成本高:需要同时维护两套完整环境,服务器成本翻倍
  • 数据库兼容性挑战:如果涉及数据库Schema变更,需要特别处理兼容性
  • 预热问题:新环境启动后可能需要时间预热缓存、连接池等
  • 不适合有状态服务:对于长连接、会话保持要求高的场景处理复杂

工作流程:

  1. 初始狀態:藍環境執行 v1.0(生產),綠環境待命。
  2. 部署新版本:在綠環境部署 v1.1,進行內部冒煙測試。
  3. 切換流量:將負載平衡器指向綠環境,流量瞬間切換到 v1.1。
  4. 監控觀察:觀察綠環境執行狀態,確認無異常。
  5. 保留舊版本:藍環境保持 v1.0 一段時間(如 24 小時),作為快速復原的保險。

✨ 優缺點分析

優點缺點
✅ 零停機時間,切換在毫秒級完成❌ 資源成本高,需要同時維護兩套環境
✅ 快速復原,發現問題立即切回原環境❌ 資料庫 Schema 變更時需要特別處理相容性
✅ 新環境可完整測試後再接管流量❌ 不適用於有狀態服務(如 WebSocket 長連線)

5.2 金絲雀發布:「小步快跑」的灰度策略

金絲雀發布得名於歷史上的「煤礦金絲雀」——礦工帶著金絲雀下礦井,如果金絲雀出現異常,說明有毒氣體外洩,礦工立即撤離。在軟體發布中,金絲雀發布就是先讓一小部分使用者試用新版本,觀察沒有問題後再逐步擴大範圍。

金丝雀发布
灰度发布策略,小流量先行验证新版本
流量分配比例拖动滑块调整新旧版本流量占比
稳定版 v1.0.090%
金丝雀 v1.1.010%
实时流量模拟 总请求: 0 | 稳定版: 0 | 金丝雀: 0
用户请求
负载均衡器
⚖️
Canary:10%
后端服务
稳定版 v1.0.0
📦S1
📦S2
📦S3
金丝雀 v1.1.0
🧪C1
🧪C2
金丝雀发布最佳实践
📊渐进式放量
  • 1% → 5% → 10% → 25% → 50% → 100%
  • 每个阶段观察至少15-30分钟
  • 关键指标:错误率、延迟、吞吐量
🎯精准用户选择
  • 内部员工/测试用户先行
  • 按地域:选择特定区域用户
  • 按用户属性:VIP用户或普通用户
  • 按设备类型:iOS/Android/Web
🛡️自动回滚机制
  • 错误率超过阈值自动回滚
  • P99延迟异常触发告警
  • 关键业务指标下降自动回滚
  • 一键回滚:30秒内恢复旧版本
📈监控与指标
  • 基础设施:CPU、内存、磁盘、网络
  • 应用指标:QPS、错误率、延迟分布
  • 业务指标:转化率、订单量、收入
  • 用户体验:页面加载时间、交互延迟

核心思想:

  1. 小流量先行:先將 1% 的流量導入新版本伺服器。
  2. 觀察指標:持續監控錯誤率、延遲、業務關鍵指標。
  3. 逐步放量:如果一切正常,逐步將比例提升到 5%、10%、25%、50%、100%。
  4. 快速復原:一旦發現異常,立即將所有流量切回舊版本。

💡 金絲雀發布的優勢

優勢說明
🎯 風險可控即使新版本有嚴重 Bug,也只影響少量使用者
📊 真實驗證在真實生產環境驗證,比測試環境更可靠
🚀 快速迭代團隊可以更自信地頻繁發布新功能
💰 資源友善不需要像藍綠部署那樣準備兩套完整環境

6. 核心問題四:如何讓系統自己「呼吸」?

6.1 自動擴縮容:讓系統像餐廳一樣「靈活排班」

想像你開了一家餐廳:

  • 午餐尖峰時段:需要 10 個服務生,但下午 3 點離峰時段只需要 2 個
  • 如果一直維持 10 個**:人事成本爆炸
  • 如果一直只有 2 個:尖峰時段顧客等不及,全跑了

自動擴縮容(Auto Scaling) 就是讓系統像餐廳一樣「靈活排班」——忙的時候自動加伺服器,閒的時候自動減伺服器。

自动扩缩容
基于CPU、内存、QPS的智能弹性伸缩
扩容指标:
实时监控 实时
💻CPU使用率
45%
扩容阈值: 70%缩容阈值: 30%
🧠内存使用率
60%
扩容阈值: 75%缩容阈值: 40%
QPS
650req/s
扩容阈值: 1000/s目标: 800/s
🖥️运行实例
3个实例
最小: 2最大: 10
1
2
3
4
5
6
7
8
9
10
扩缩容历史最近 5 次操作
📈
扩容: 2 → 3 实例
CPU使用率超过70%
10:23
📉
缩容: 4 → 3 实例
CPU使用率低于30%
09:15
📈
扩容: 3 → 4 实例
QPS达到1000/s
08:42
📈
扩容: 2 → 3 实例
内存使用率超过75%
07:30
📉
缩容: 5 → 4 实例
流量下降
06:20
自动扩缩容最佳实践
⏱️
冷却时间
设置适当的冷却时间(通常3-5分钟),避免扩缩容操作过于频繁导致的震荡
📊
多指标综合
不要依赖单一指标,结合CPU、内存、QPS、连接数等多维度进行综合判断
🎯
目标利用率
设置合理的资源目标利用率(如70%),预留足够的缓冲应对突发流量
快速扩容
扩容操作应该比缩容更激进,确保系统能快速应对流量增长

6.2 擴充指標的選擇

自動擴縮容的核心是回答一個問題:** 什麼時候該加機器?什麼時候該減機器?

常見的決策指標:

指標擴充閾值縮減閾值適用情境
CPU 使用率> 70%< 30%計算密集型應用
記憶體使用率> 75%< 40%記憶體密集型應用
QPS(每秒請求數)> 1000/s< 400/sAPI 閘道器、Web 服務
連線數> 5000< 1000資料庫、訊息佇列
自訂業務指標視業務而定視業務而定特定業務情境

💡 擴充策略的「坑」與「解」

坑 1:擴充反應太慢,流量洪峰已經把系統打掛了

某電商大促期間,設定 CPU > 80% 觸發擴充,但監控擷取有 1 分鐘延遲,新執行個體啟動需要 3 分鐘。結果流量來得太快,擴充還沒完成,伺服器已經被打掛。

解決方案:

  • 提前擴充:基於歷史資料預測流量尖峰,提前 30 分鐘開始擴充
  • 多級閾值:設定 60% 預警(開始預熱新執行個體)、70% 正式擴充、80% 緊急擴充
  • 快速擴充:使用容器化部署,新執行個體 30 秒內啟動(相比虛擬機器 3-5 分鐘)

坑 2:擴充太激進,成本爆炸

某創業公司設定了激進的自動擴充策略:CPU > 50% 就擴充。結果一個正常的業務波動就觸發了擴充,伺服器數量從 5 台膨脹到 30 台,月底雲端帳單嚇哭了 CTO。

解決方案:

  • 設定擴充冷卻時間:一次擴充後,至少等待 5 分鐘才能再次擴充
  • 設定最大執行個體數:max = 目前執行個體數 × 2,防止無限膨脹
  • 區分突刺和趨勢:只有連續 3 個週期都超過閾值才擴充,避免單點突刺觸發

坑 3:縮減太快,剛擴充的機器馬上就縮了

某團隊設定了 CPU < 30% 縮減。擴充後流量還在消化,CPU 短暫回落到 25%,觸發了縮減。剛縮完 CPU 又飆到 80%,又觸發擴充——系統在「擴充-縮減-擴充」中瘋狂震盪。

解決方案:

  • 縮減更保守:擴充閾值 70%,縮減閾值 25%,中間有足夠的緩衝帶
  • 縮減冷卻時間更長:擴充後至少等待 10 分鐘才能縮減
  • 漸進式縮減:一次只縮 1 台,觀察後再決定要不要繼續縮

7. 實戰:如何選擇負載平衡器?

7.1 主流負載平衡器對比

特性NginxHAProxyEnvoy雲端廠商負載平衡
定位高效能反向代理/負載平衡開源負載平衡雲端原生代理託管負載平衡
效能極高(C 語言,事件驅動)高(事件驅動)高(C++/Rust)極高
功能豐富度基礎負載平衡、靜態檔案、快取豐富的負載平衡演算法進階路由、觀測功能全面
組態設定設定檔(nginx.conf)設定檔(haproxy.cfg)API/設定檔UI 主控台
擴充C 模組/Lua 指令碼Lua 指令碼WASM/Filter外掛程式
適用情境靜態資源、七層負載平衡、SSL 終結七層負載平衡、高可用性服務網格、多雲端快速上手

💡 選型建議

決策樹:

選擇負載平衡器:

├─ 只需要基礎的四層負載平衡?
│  ├─ 是 → LVS(開源免費)或 雲端廠商 NLB
│  └─ 否 → 繼續

├─ 需要服務網格、多雲端部署?
│  ├─ 是 → Envoy
│  └─ 否 → 繼續

├─ 需要極其複雜的組態設定和外掛程式?
│  ├─ 是 → HAProxy
│  └─ 否 → 繼續

├─ 需要高效能 + 簡單組態設定?
│  ├─ 是 → Nginx(首選)
│  └─ 繼續

├─ 想要託管維運?
│  ├─ 是 → 雲端廠商負載平衡(AWS ALB、阿里雲 SLB)
│  └─ Nginx 自建

8. 總結:負載平衡的核心思維

8.1 核心原則回顧

原則含義實踐要點
分層L4 處理「快遞分揀」(快但簡單)L4 處理資料庫、遊戲;L7 處理 Web、API
冗餘單點故障是架構的敵人透過多執行個體、多區域部署提升可用性
漸進發布新版本不要「一刀切」藍綠部署實現零停機;金絲雀實現風險可控
彈性系統應該像生命體一樣「呼吸」忙時自動擴充,閒時自動縮減

8.2 設計檢查清單

在引入負載平衡前,問自己以下問題:

  • [ ] 是否真的需要負載平衡?(單機效能是否真的不夠)
  • [ ] 選擇 L4 還是 L7?(根據業務情境)
  • [ ] 如何處理工作階段保持?(Cookie、IP 雜湊、工作階段表)
  • [ ] 如何實現健康檢查?(主動、被動、閾值設定)
  • [ ] 如何實現零停機?(藍綠部署、金絲雀)
  • [ ] 如何實現彈性?(擴縮指標、冷卻時間、最大執行個體數)

9. 名詞速查表

名詞英文解釋
負載平衡器Load Balancer將流量分發到多個後端伺服器的裝置或軟體
四層負載平衡L4 Load Balancing基於傳輸層(TCP/UDP)的負載平衡
七層負載平衡L7 Load Balancing基於應用層(HTTP/HTTPS)的負載平衡
健康檢查Health Check定期檢查後端伺服器的健康狀態的機制
工作階段保持Session Persistence確保同一使用者的請求始終路由到同一台伺服器
黏性工作階段Sticky Session另一種稱呼,同 Session Persistence
藍綠部署Blue-Green Deployment兩套環境切換的零停機發布策略
金絲雀發布Canary Release小流量先行驗證的灰度發布策略
自動擴縮容Auto Scaling根據負載自動增加或減少伺服器數量
水平擴充Horizontal Scaling增加伺服器數量來提升處理能力
垂直擴充Vertical Scaling提升單機組態(CPU、記憶體)來提升處理能力
多區域Multi-Region在多個地理區域部署服務
多活Active-Active多個區域同時對外提供服務
主備Active-Standby只有一個區域提供服務,其他待命
資料同步Data Replication跨區域的資料複製機制
RTORecovery Time Objective (RTO)復原時間目標,系統故障後需要在多長時間內復原
RPORecovery Point Objective (RPO)復原點目標,系統故障後可以接受的資料遺失量