當你的 WordPress 平常跑得好好的,卻在活動開跑、文章爆紅或檔期促銷那幾個小時突然變慢、甚至整站打不開,問題通常不是程式寫壞,而是單一台主機的處理量到頂了。這時候把主機規格往上加(加 CPU、加記憶體)只能撐一陣子,總有一台機器拉不動的天花板。負載平衡 WordPress 的思路剛好相反:與其逼一台主機更強,不如擺好幾台一模一樣的主機,前面放一個 load balancer 把流量分散出去。
這篇會從「水平擴展到底在做什麼」講起,帶你看懂一套多主機架構的組成、load balancer 的選擇與分流演算法,並把 WordPress 跨多台主機時最容易翻車的幾個地雷一次講清楚。這些地雷大多數教學都跳過,卻是實際導入時最花時間的部分。
負載平衡是什麼,跟 WordPress 水平擴展是同一件事嗎
負載平衡是把進來的網路流量分散到多台主機上的技術,水平擴展則是「靠增加主機數量來提升處理量」的策略,兩者是搭配關係:負載平衡是水平擴展能成立的前提。
先分清楚兩種擴展方向。垂直擴展(scale up)是把同一台主機升級,加大 CPU、記憶體或硬碟;水平擴展(scale out)是維持單台規格不變,改成多擺幾台一樣的主機一起服務。垂直擴展設定簡單,但單台終究有上限,而且升級時往往要重開機、會中斷服務;水平擴展沒有單機天花板,理論上想撐多少流量就加多少台,還順帶換來「一台掛了其他台頂上」的容錯能力。
load balancer 就是站在所有主機前面的那個分流者。使用者連到你的網站時,請求其實是先打到 load balancer,再由它依照當下各台主機的忙碌程度,把這個請求轉給最適合的一台處理。對使用者來說,網址沒變、體感沒變;對後端來說,沒有任何一台主機需要獨自扛下全部流量。
所以負載平衡與水平擴展不是兩個可以分開選的方案,而是同一套架構的兩個面向:你想水平擴展,就一定得有 load balancer 來分流;你裝了 load balancer,背後就得有多台主機可分。
你的 WordPress 真的需要負載平衡嗎
多數網站其實還不需要負載平衡,先別急著上多主機架構。在跳到多台主機之前,先確認你已經把單台主機能做的事做滿,否則只是把效能問題搬到更貴、更複雜的環境裡重演一次。
判斷的順序建議這樣走。第一步、先看瓶頸是不是出在沒做快取。一個還沒導入頁面快取與物件快取的 WordPress,光是加上快取外掛或主機層級快取,往往就能把可承載的同時上線人數拉高好幾倍,這一步幾乎零成本。第二步、確認是不是垂直擴展就能解決。如果流量是穩定成長而非劇烈尖峰,把主機規格往上加一階通常更省事,設定單純、也沒有跨主機同步的麻煩。
真正適合上負載平衡的,是符合下列任一種情況的網站:
- 流量有明顯尖峰:例如售票、報名、限時促銷、新聞爆量,平常流量不高但某幾個小時會暴衝十倍以上,單台主機很難為了那幾小時長期養著高規格。
- 不能接受停機:金流、會員服務、線上課程這類網站,一旦單台主機故障就等於全站中斷,需要靠多台主機互為備援。
- 單台已到實體上限:主機規格已經升到方案頂端,再往上加效益遞減或根本沒得加。
如果你的網站流量平穩、偶爾慢一下也能接受,那麼負載平衡帶來的設定複雜度與成本,多半划不來。把這個決策想清楚,比急著架多主機更重要。
一套負載平衡的 WordPress 架構長什麼樣
一套能正常運作的多主機 WordPress,核心是「讓每一台網站主機都變成可替換的、不保存獨有狀態的」節點,再把資料庫、媒體檔、使用者狀態這些「全站共用的東西」抽出來放到集中的地方。
整體資料流大致如下:
進站流量
分流與健康檢查
PHP 節點
PHP 節點
PHP 節點
MySQL 主從
媒體檔
session 與快取
逐層拆開來看,這套架構有四個必備元件。
多台 PHP 網站主機:每一台都裝著一模一樣的 WordPress 程式碼,彼此之間不該保存任何「只有自己有、別台沒有」的資料。這個原則叫無狀態(stateless),是水平擴展能成立的關鍵,後面會專門講為什麼 WordPress 預設並不無狀態。
集中的資料庫:所有網站主機都連到同一套資料庫,文章、設定、訂單才不會因為使用者這次連到 A、下次連到 B 就對不上。流量大時資料庫本身也會擴展,常見做法是一主多從(primary-replica),寫入打到主庫、讀取分散到多個從庫。
集中的媒體儲存:使用者上傳的圖片、附件不能各存各台主機,否則在 A 上傳的圖,連到 B 的人就看不到。實務上會把 wp-content/uploads 搬到物件儲存服務(例如 Amazon S3、Google Cloud Storage),讓所有主機讀同一份。
集中的快取與 session:登入狀態、購物車這類使用者狀態,以及物件快取,要放到所有主機都連得到的 Redis 或 Memcached,而不是各台主機自己的記憶體裡。
四個元件的共同邏輯就一句話:把「全站共用的狀態」從個別主機身上剝離出來,集中保管。剝得越乾淨,網站主機就越能隨意增減,水平擴展才順。
load balancer 有哪些類型,WordPress 該選哪一種
load balancer 主要分成軟體、雲端、硬體與 DNS 四種,對絕大多數 WordPress 網站來說,軟體或雲端負載平衡器是最務實的選擇。
軟體負載平衡器指的是跑在一般主機上的程式,常見的是 Nginx 與 HAProxy。它彈性高、成本低、設定貼近 WordPress 的實際需求,可以順手處理 SSL 終止、靜態檔快取與分流規則。代價是你得自己維運這台 load balancer,包含它本身的高可用(避免它變成單點故障)。
雲端負載平衡器是雲端平台託管的服務,例如 Amazon 的 Elastic Load Balancing、Google Cloud Load Balancing。它最大的好處是託管、會自動跟著流量調整、也內建健康檢查,搭配雲端的自動擴展群組可以做到流量上來自動加主機、流量退去自動收主機。適合流量起伏大、又不想自己顧 load balancer 的團隊。
硬體負載平衡器是專用的實體設備,效能與延遲表現好,但價格高、需要專業知識維護,通常只出現在大型企業或自建機房的場景,一般 WordPress 站用不到。
DNS 負載平衡則是在網域解析層做分流,依 DNS 回應把使用者導到不同主機或不同資料中心,常用於跨地理區域把流量導到最近的機房以降低延遲。它調度比較粗,多半是搭配上面幾種一起用,而不是單獨擔綱。
選擇上有一條簡單的分界:如果你已經在某家雲端平台上,直接用該平台的雲端負載平衡器加自動擴展最省心;如果你是在 VPS 或自管主機上自己搭,Nginx 或 HAProxy 是社群資源最多、最容易找到設定範例的組合。
負載平衡演算法怎麼選,WordPress 的登入與購物車要特別注意
分流演算法決定 load balancer 把每個請求丟給哪一台主機,常見的有輪詢、最少連線與 IP 雜湊三種,選哪一種要看你的網站有沒有「同一個使用者必須一直連到同一台」的需求。
輪詢(round robin)最單純,請求按順序一台接一台輪流發。設定容易、分配平均,適合每個請求負擔差不多、且網站本身已經做到無狀態的情況。對於以瀏覽文章為主、登入狀態已集中存放的 WordPress,輪詢通常就夠用。
最少連線(least connections)會把新請求送給「當下連線數最少」的那台主機。當不同請求的處理時間差異很大時(例如有些頁面要跑大量資料庫查詢、有些只是回傳靜態內容),它比輪詢更能避免某台主機被重活塞滿,適合動態內容多、後台操作頻繁的站。
IP 雜湊(IP hash)依使用者來源 IP 算出固定的對應主機,讓同一個訪客每次都連到同一台。這其實是實作工作階段保持(sticky session,黏著式工作階段)的一種方式。
這裡有個 WordPress 特別容易踩的判斷。如果你還沒把登入狀態與購物車搬到集中的 Redis,那麼使用者的這些狀態就只存在「他第一次連到的那台主機」上,這時若用輪詢,下一個請求被分到別台,使用者就會莫名被登出、購物車清空——WooCommerce 結帳流程尤其敏感。短期應急可以開 sticky session(用 IP 雜湊或 load balancer 的工作階段保持功能)把同一人綁在同一台。但更乾淨的做法,是把 session 集中到 Redis、讓網站真正無狀態,然後就能放心用輪詢或最少連線,獲得更平均的分流與更好的容錯。換句話說,sticky session 是過渡手段,集中 session 才是治本。
WordPress 跨多台主機最常踩的雷
WordPress 預設是為「單機」設計的,直接搬到多主機而不調整,會在幾個地方默默出錯,這些才是導入時真正花時間的部分。把下面這幾項處理好,多主機架構才算真的站穩。
使用者上傳檔案各存各台:前面提過,wp-content/uploads 預設寫在本機磁碟,多主機時在 A 上傳的圖只有 A 有。解法是把媒體改放物件儲存(搭配像 WP Offload Media 這類外掛自動轉存),或退而求其次用網路檔案系統與 rsync 同步。物件儲存通常是維護成本較低的選擇。
wp-cron 在每一台重複執行:WordPress 的排程任務 wp-cron 預設由訪客請求觸發,多主機時每一台都會各自跑一次,輕則重複寄信、重複發文,重則資料打架。正確做法是關掉內建的 wp-cron(在 wp-config.php 把 DISABLE_WP_CRON 設為 true),改由單一一台主機用系統層的排程器定時呼叫,確保整個叢集只跑一份排程。
物件快取沒集中,各台資料不一致:如果物件快取存在各台主機自己的記憶體,A 更新了內容、清掉自己的快取,連到 B 的人卻還拿到 B 的舊快取。物件快取一定要指向集中的 Redis 或 Memcached,所有主機讀寫同一份,內容更新才會一致地反映到每一台。
SSL 終止後抓不到真實協定與 IP:常見架構是讓 load balancer 負責 SSL 終止,再用 HTTP 連到後端主機。這時 WordPress 看到的是 HTTP 連線,is_ssl() 會判斷錯誤,導致無窮重導或混合內容。要在 wp-config.php 依 HTTP_X_FORWARDED_PROTO 標頭還原 HTTPS 判斷。同理,後端主機看到的來源 IP 會全部變成 load balancer 的 IP,需要改看 X-Forwarded-For 標頭才能取得訪客真實 IP,否則防火牆、留言記錄、流量分析都會失準。
每台主機環境不一致:多主機的前提是每一台「一模一樣」,包含 WordPress 核心、外掛、佈景主題版本與設定都要對齊。只要有一台版本不同步,使用者連到它時就可能看到不同行為。實務上會用部署流程或映像檔讓所有主機從同一份來源建立,避免手動逐台更新造成漂移。
這幾個雷的共同根源都是同一件事:WordPress 預設把狀態存在本機。把狀態集中、把環境對齊,多主機才能真正當成可替換的節點來用。
健康檢查、故障轉移與自動擴展是怎麼運作的
load balancer 不只是把流量平均發出去,它還會持續檢查每台主機是否健康,並在主機故障時自動把流量導開,這套機制才是多主機架構能提升可用性的真正原因。
健康檢查是 load balancer 定期對每台主機發出探測請求,確認它還活著、還能正常回應。檢查項目可以從最簡單的「某個網址有沒有回 200」,到比較深入的「資料庫連得上嗎、CPU 與記憶體是否還有餘裕」。檢查頻率與項目可依網站需求調整,越頻繁越能及早發現問題,但也會增加一些額外負擔。
故障轉移是接在健康檢查後面的動作:某台主機檢查沒過,load balancer 就把它移出可服務的名單,新進來的流量只會分給健康的主機;等它恢復、重新通過檢查,再把它放回名單。對使用者來說,過程中網站持續可用,不會因為一台主機出問題就整站中斷。這也是為什麼多主機能讓你「不停機維護」:要更新或保養某台時,先讓它退出名單即可。
自動擴展則把這套機制再往前推一步。搭配雲端平台的自動擴展群組,系統可以依預設條件(例如 CPU 使用率或同時連線數超過某個門檻)自動新增主機,流量退去後再自動移除,讓你只在需要時才付多台的成本。這對前面提到的「平常流量低、特定時段暴衝」的網站特別划算。
要提醒的是,健康檢查跟故障轉移處理的是「主機」這一層。如果集中的資料庫、Redis 或物件儲存掛了,那是全站共用元件的單點故障,網站主機再多也救不回來。所以這些共用元件本身也要做高可用(例如資料庫主從、Redis 叢集),整套架構的可用性才完整。
導入前後該監控什麼,收款情境又要注意什麼
多主機架構不是設定完就一勞永逸,持續監控才能確保分流真的有效、也才能及早抓到問題。導入後該盯著的指標,可分成主機層與 load balancer 層兩塊。
主機層要看每一台的 CPU、記憶體、磁碟使用率與網路流量,確認負載真的有被平均分散,而不是某一台特別忙、其他台閒著——後者通常代表分流演算法或 sticky session 設定需要調整。WordPress 層則可以觀察 PHP 執行時間、資料庫查詢效能,找出拖慢回應的外掛或慢查詢。load balancer 層要看請求在各主機間的分布、各主機的回應時間與錯誤率,並對停機或回應變慢設好告警。
如果你的網站涉及收款(例如會員費、商品結帳),多主機環境下有兩件事值得客觀留意,但這裡只談架構面、不展開金流串接的設定。第一、結帳流程高度依賴使用者狀態(登入、購物車),是前面講的 session 集中問題最敏感的地方,務必確認 session 已放到集中的 Redis,或至少在結帳路徑上維持 sticky session,避免使用者付到一半被登出。第二、付款服務商往往會以伺服器 IP 或回呼網址(callback)來驗證來源,多主機時對外 IP 可能不只一個,且 load balancer 會改寫來源 IP,這部分要事先確認金流服務商的白名單與回呼設定能涵蓋你的架構。細節依各家金流服務商規範而定,導入前先確認清楚。
從單機到多主機,真正的門檻不在「裝一個 load balancer」,而在把 WordPress 改造成無狀態、把共用元件集中並做好高可用。先確認自己是不是真的需要這套架構,再從快取與垂直擴展這些低成本選項開始排除瓶頸;確定要上多主機時,把 session、媒體、wp-cron、SSL 與環境一致性這幾個地雷逐一拆掉,你的網站才能在下一次流量暴增時穩穩接住。