你打開一個網站時,直覺上很容易想像成:

瀏覽器 → 伺服器 → 回傳網頁

這在小型網站上確實可能是真的。一台機器同時跑 Web Server、API 和資料庫,只要流量不大,架構甚至相當合理。

問題是,伺服器不是無限大的。

每一個 request 都會消耗 CPU、記憶體、網路頻寬、檔案描述符與資料庫連線。假設一台伺服器穩定能處理每秒 1,000 個請求,某天流量突然變成每秒 5,000 個,單純要求它「再努力一點」不會讓硬體憑空多出五倍資源。

這時通常有兩條路:把一台機器變得更強,或增加更多機器。

前者稱為 Vertical Scaling,也就是垂直擴充;後者則是 Horizontal Scaling,也就是水平擴充。

而當你開始水平擴充,一個新的問題立刻出現:使用者到底該連哪一台?

這就是 Load Balancer 出場的地方。

一、Load Balancer 到底在做什麼?

假設我們現在有三台完全可以處理相同 API 的伺服器:

Server A

Server B

Server C

如果所有使用者仍然只連 Server A,那 B 和 C 就算存在也沒有意義。因此,我們可以在它們前面放一個入口:

Client

↓

Load Balancer

├─ Server A

├─ Server B

└─ Server C

使用者不需要知道後面到底有幾台伺服器。對外看起來仍然只有一個網站、一個網域名稱與一個服務入口。

Load Balancer 收到 request 後,選擇一台適合的後端伺服器,再把 request 送過去。後端處理完成後,response 再沿著路徑回到使用者。

所以負載平衡器最核心的任務可以濃縮成一句話:

把流量合理地分配給多個可以提供相同服務的節點。

二、為什麼不能隨便輪流丟?

最簡單的策略確實就是輪流。

第一個 request 給 A,第二個給 B,第三個給 C,第四個再回到 A。這種方法稱為 Round Robin。

它的優點是簡單,而且當每台伺服器能力相近、每個 request 的成本也差不多時,效果通常不錯。

但真實世界沒有那麼整齊。

有些 request 可能 20 毫秒就完成,有些卻要跑複雜查詢、處理圖片或呼叫外部 API,需要好幾秒。如果 Server A 剛好卡著很多慢 request,這時繼續機械式把新流量丟給它,就不一定合理。

因此還有其他常見策略。

Least Connections 會優先選擇目前連線較少的伺服器。Weighted Round Robin 則允許不同伺服器具有不同權重,例如效能較強的機器分到更多流量。某些系統還會依延遲、CPU 使用率或其他即時指標做更動態的決策。

沒有一種演算法永遠最好。真正要問的是:你的 workload 有什麼特性?

三、如果其中一台伺服器死掉呢?

負載平衡真正重要的價值,不只是「平均分流量」。

假設 Server B 突然當機。如果 Load Balancer 不知道這件事,仍然每三個 request 就送一個給 B,那大約三分之一的使用者會看到錯誤。

所以負載平衡器通常會做 Health Check,也就是健康檢查。

例如定期呼叫:

GET /health

如果 Server A 回傳正常狀態,代表它仍可接受流量;如果 Server B 連續逾時或回傳錯誤,就暫時把它從可用節點清單中移除。

此時流量變成:

Load Balancer

├─ Server A ✓

├─ Server B ✗

└─ Server C ✓

使用者甚至可能完全不知道 B 剛剛壞掉。

等 B 修復並重新通過健康檢查後,它又可以被加入流量池。

這就是高可用性架構中非常重要的一個概念:故障不一定要等於整個服務故障。

四、Load Balancer 和 Reverse Proxy 有什麼不同?

兩者非常容易混在一起,因為實作上常常是同一套軟體完成。

Reverse Proxy 的核心概念,是由一個代理入口代表後端伺服器接收 client request。它可能負責 TLS termination、快取、路由、壓縮或隱藏內部架構。

Load Balancing 則特別關注「有多個後端時,流量要分給哪一個」。

因此:

Reverse Proxy 是角色與流量位置的概念;Load Balancing 是流量分配的能力。

一個 Reverse Proxy 可以只代理一台 upstream,完全不做負載平衡;也可以代理十台 upstream,同時扮演 Load Balancer。

像 Nginx、HAProxy,以及許多雲端服務,都能同時涵蓋這些能力。

五、加了更多伺服器,為什麼登入可能突然出問題?

這是水平擴充最經典的坑之一。

假設使用者登入後,Server A 把 Session 存在自己的記憶體:

Server A memory:user 123 已登入

下一個 request 經過 Load Balancer,卻被送到 Server B。

Server B 的記憶體裡沒有這個 Session,於是它可能認為使用者根本沒登入。

結果就是一個很詭異的網站:一下登入、一下登出。

有幾種常見解法。

第一種是 Sticky Session,也稱 Session Affinity。Load Balancer 盡量讓同一個使用者持續被送到同一台伺服器。

第二種,也是更容易水平擴充的方式,是不要把重要 Session 狀態綁死在單一 Web Server。可以把 Session 放到所有節點都能存取的資料儲存,例如 Redis,或採用適合的 token-based authentication 設計。

這帶出一個重要原則:

當後端節點可以任意增加、移除與替換時,應盡量避免讓某個 request 必須依賴「剛好是上一台機器」才能成功。

六、Load Balancer 自己不就變成單點故障?

對。

如果所有流量都必須經過一台 Load Balancer,而這台機器掛掉,後面的十台伺服器全部健康也沒有用。

所以正式的高可用架構通常不會真的只放一個不可替代的 Load Balancer。

實際系統可能使用多個負載平衡節點、雲端供應商提供的 managed load balancer、Anycast、故障轉移機制,或其他高可用設計,讓「入口」本身也具有冗餘。

這也是架構設計裡一個反覆出現的思考方式:

每當你為了解決單點故障而加入一個新元件,都應該再問一次——這個新元件自己是不是新的單點故障?

七、L4 與 L7 Load Balancer 是什麼?

你可能會看到 Layer 4 和 Layer 7 Load Balancer 這兩個詞。

L4 通常根據較底層的網路資訊做轉送,例如 IP 位址與 TCP/UDP port。它不需要深入理解 HTTP 網址代表什麼,因此通常可以用較通用、較低層的方式處理流量。

L7 則工作在應用層,能理解 HTTP request 的內容。例如它可以設定:

/api/* → API servers
/images/* → image servers
/admin/* → admin backend

甚至可以依 Host、Header、Cookie 等資訊決定路由。

所以 L7 Load Balancer 不只是「三台伺服器選一台」,還能進行應用層的智慧路由。

八、Load Balancer 能讓任何系統無限擴充嗎?

不能。

這是很重要的限制。

你可以把 Web Server 從 1 台擴充到 100 台,但如果 100 台最後全部在搶同一個資料庫,而資料庫每秒只能承受固定數量的查詢,瓶頸只是從 Web Server 移到了 Database。

同樣地,共用檔案系統、外部 API、message queue、cache、網路頻寬,都可能成為下一個限制。

因此 Scaling 並不是「前面放一個 Load Balancer 就結束」。

它更像是一個持續尋找瓶頸的過程:

流量增加

→ Web Server 不夠
→ 水平擴充 Web Server
→ Database 成為瓶頸
→ 優化查詢、Cache、Read Replica 或重新設計資料架構
→ 又出現新的瓶頸

系統規模越大,效能問題越不像單一零件的問題,而更像整條 request path 的問題。

九、一次 request 實際可能怎麼走?

把前面幾個概念串起來,一個現代網站的 request 可能長這樣:

Browser

↓

DNS

↓

CDN / Edge

↓

Load Balancer

↓

Server B

↓

Cache / Database

↓

Server B

↓

Load Balancer

↓

Browser

如果 Server B 壞掉,下一個 request 可能被送到 Server A;如果某個靜態檔案已經被 CDN 快取,request 甚至根本不需要抵達 origin server。

使用者看到的是一個網址,但網址背後可能是一整套會動態分配、容錯與擴充的系統。

十、什麼時候真的需要 Load Balancer?

不是所有專案一開始都需要。

如果你的個人網站每天只有幾十個訪客,為了「未來可能有百萬流量」先架十台 server、Redis cluster、Kubernetes 和多層 Load Balancer,通常只會讓系統更難維護。

架構的複雜度本身也是成本。

但當你開始遇到以下需求時,負載平衡就變得有意義:單台伺服器已經無法承受尖峰流量;服務不能因一台機器故障就完全離線;需要在部署時逐台替換節點;或需要把不同類型的 request 導向不同後端。

好的架構不是元件越多越專業,而是在需要的時候,用足夠簡單的方式解決真實存在的限制。

結語:Load Balancer 解決的其實是「一台不再夠用」之後的世界

一開始,網站可以非常簡單:一個 client、一台 server。

但當流量、可靠性與部署需求成長後,「只有一台」會同時帶來效能上限與單點故障。Horizontal Scaling 讓我們可以增加更多後端節點,而 Load Balancer 則負責讓這些節點真正成為一個共同提供服務的系統。

它不會讓系統自動變得無限快,也不能消除所有瓶頸;它真正提供的是一個重要能力:讓流量不必依賴某一台特定機器。

理解這一點之後,再看到大型網站前面的 CDN、Reverse Proxy、Load Balancer、Web Server 與 Database,就不再只是滿滿的方框,而是一條有理由存在的 request 路徑。

把概念放回真正的系統流程裡看,通常比只背名詞更容易理解它。