WordPress 用Haproxy進行負載平衡

GCP 的 WordPress 效能改善,除了之前提到的「 網站效能改善方案, 啟用 Apache Event MPM」,我也嘗試過利用動態開啟額外的虛擬機來做負載平衡。主要的概念,就是平常用免費的 f1-micro 方案,在負載比較重的時段,才動態的將第2台虛擬開啟來做服務。這樣可以最有效的降低花費,當然第一首選還是以改善軟體的效能來達成更多的服務,也就是前面說的啟用 Event MPM,甚至換到 Ngnix 去,第2才是用額外的虛擬機來服務。

做多台機器的負載平衡,說實在是比較麻煩,所以也是最後關頭才會用上吧。不過繼然都試了,就把他們寫下來吧。

配置流程

我目前的配置,還是以在本地端做測試成功而已,沒真實的在 GCP 上面執行過,這點可能是要先說明的。所需的步驟有點繁雜,可能要有點耐心才看的完~~~我這邊也以在本地端的虛擬機配置來當做解說的方式。VM-A 和 VM-B 的 IP 分別假定是 192.168.100.1與 192.168.100.2。

  1. 先參考「 驗証 Bluehost WordPress 備份檔案的復原流程」文章,將 GCP 的備份,復回到本地端的一台虛擬機 A (VM-A)內,VM-A 會是主台,假定是不會關機的,由它來分配連線給其它伺服器。
  2. 將 VM-A 上的 WordPress 資料庫連線方式改成指定 IP 而非 127.0.0.1,而且修改 MySQL 允許遠端連入。這樣是為了讓 VM-B 也可以,透過網路將資料寫入 VM-B。
  3. 將 VM-A Clone 出另一台 VM-B
  4. 在 VM-A 上安裝 NFS Server,並將 WordPress 的目錄分享出去
  5. 在 VM-B 上將 VM-A 上的 WordPress 目錄 Mount 到本地的 wordpress 錄徑。
  6. 在 VM-A 上面安裝 Haproxy ,並設定負載平衡的機器為 VM-B 。
  7.  試著開啟/關閉 VM-B ,看看是否 Log 上是否紀錄 VM-B 有服務到連線。

 

是吧,步驟有點多….有需要的人可能要有點耐心,也歡迎提問一起討論。

 

步驟1 – 還原 WordPress 備份檔檔案

如前述,請參考「 驗証 Bluehost WordPress 備份檔案的復原流程」文章,將 GCP 的備份,復回到本地端的一台虛擬機 A (VM-A)內。接著修改 Web Server 服務的 Port, 從 443 改成 444。443 會用於對外轉接的服務接口,而444這是內部服的真正接口。請修改下列2個檔案內的 443 成 444:

 

步驟2 – 設定 MySQL 新的連線方式

修改 root 允許連入的位置

先以 root 登入 mysql,下達下面指令來允許從任意位置以 root 連進 MySQL Server。其中的 % 就代表任意位置,也可改成你允許的IP。而 123456 是指定帳號 root 的密碼。這裡的帳號密碼是以測試為例,實際上請使用自己的帳密。

 

修改 MySQL Server 服務的 IP

修改 mysql 設定檔 /etc/mysql/mysql.conf.d/mysqld.cnf

變更 bind address 與加入免 name resolve,這樣才可以接受非本地端的 IP 連線,並且不進行 DNS解析。

 

重啟 MySQL Server

 

驗証非本地的資料庫連線

重新試試,看可否連線

如果成功連上,就代表可從非本地端連入。

修改 WordPress 資料庫的連線 IP

最後將 WordPress 連線的資料庫 IP,從 127.0.0.1 改成 192.168.100.1,這樣 VM-A / VM-B 才會共用一個資料庫。

指定 MySQL Server IP

步驟3- 產生另一台負載平衡的 VM

接下來將 VM-A Clone 出另一台 VM-B,步驟依虛擬機(vmware or virtualbox)的種類而不同,這邊就不詳細描述。其中要修改的是其 IP,這邊我們就假定 VM-A/B 的 IP是 192.168.100.1與 192.168.100.2,而其網路是橋接在一起的。

步驟4- VM-A 利用 NFS 分享 WordPress 檔案

先安裝 NFS Server

 

安裝完成後,編輯 /etc/exports 來設定NFS要分享的目錄

 

重啟 nfs server

 

步驟5- 設定 VM-B 使用 VM-A 檔案

在 VM-B 安裝 NFS Client,才能 mount VM-A 上 NFS 的分享

 

在 VM-B 內將下列命令加到 /etc/rc.local 內,在開機時就將 WordPress 的目錄掛載

由於 Ubuntu 16.04 的 /etc/rc.local 預設是不是執行的,請將其權限改成可以執行,開機才會執行

 

步驟6- 在 VM-A 上設定 HAPrxoy

使用命令 apt-get install haproxy 來安裝 haproxy, 然後修改/etc/haproxy/haproxy.cfg成下面內容。

 

上面的設定值有幾個重點

  1. listen admin_stats: haproxy 有內建的管理 / 監控網頁頁面可以讓使用者觀察流量,看看與設定的配置結果是否一致。本項設定會在 port 26000 上服務,如果你有多個IP想要只綁定在特定 IP 上才允許多入,可以把這裡的 0.0.0.0 改成想要的 IP 即可。uri 設定指定了要服務的的網址名稱,以這裡的 “/haproxy_status” 為例,就表示要連到 http://192.168.100.1:26000/haproxy_status 才能看到監控頁面。而 auth 項目,則是設定了要帳號/密碼,要輸入正確的帳號密碼才能看到管理頁面。
  2. frontend acommon: 這個設定在於設定從外連入的 port 與連接到內部負載平衡的機台。其中的 bind *:443 代表會接受所有介面的 443 port 的連入連線 (https),接受到連現後,default_backend common 設定會將流量導至名為 common 的負載服務機器設定值。
  3. backend common: 這個設定列出了所有做為負載平衡的機器。balance roundrobin 代表著負載平衡的政策會輪流服務,也是說我們設定2個服務器,每台會輪流接受新的連線,但這設定還是會受到服務器權重設定的影。server one 192.168.100.1:444 check inter 1500 rise 3 fall 3 weight 1 這是其中一台服務器的設定,其名字被命名為 “one”,流量會被導到 192.168.100.1:444 去。haproxy 每 1500ms  會檢查這台服務器是否為開機狀態,當連續三次成功 (rise 3) 就認定它是開機,連續三次失敗 (fall 3) 則認為它已關機。開機的服務器就可接受新流量,關機的則不會將流量轉發給它。而最後的 weight 則代表著權重, haproxy 會計算所有開機的服務器的權重,根據每台開機服務器所佔的權重來分配流量。

從2個服務器的設定可以看到,二台機器的權重分別為 1 與 256,也是說當VM-B開機時,都是把服務交給 VM-B來處置的。若 VM-B 關掉,則全部由 VM-A 處理。這也是為了符合可擴展性的設計,讓 VM-A 專心的處理資料轉傳與資料庫,而其它 VM-B(VM-C, VM-D …以後有更多的話),來專心處理服務。

 

完成上面的設定後,就可以執行以下命令,來啟動 haproxy 了

 

步驟7 – 負載測試

VM-B 狀態偵測

上圖是 VM-A 上執行 haproxy 時的 log。第一個紅框是一開始執行時的狀態,此時VM-A與VM-B都是在開機狀況態。此時,流量分配會以1:256都比例去分配,也就是大部份都把負載交給 VM-B了。接著,我們把 VM-B 關掉,就會出現第2個紅框的訊息,haproxy 偵測到了 VM-B 的關機,所以此時會把所有的流量交給 VM-A 執行。 最後,第三個紅框則是再度把VM-B打開,此時haproxy偵測到了這個動作,又會依照規則去分配流量了。

紀錄觀察

前面在設定 haproxy 時,已經有啟用了其內建的管理頁面。在 VM-A 上打開瀏覽器去看 http://127.0.0.1:26000/haproxy_status 就會跳出問密碼的對話框,帳密輸入 admin / admin,就可看到監控的畫面了。

當兩台機器都開機時,就可以看到大部份的負載都在機器B上。

負載都在B

當關掉B時,負載則全部落到 A

負載都在 A

 

結語

haproxy 算是一個快速經濟的負載平衡方案,目前我的作法的缺點,就是資源都押在了 VM-A 上。雖然我實際沒弄過雲端的負載平衡方案,不過我想它的們的作法應該也類似,但在架設 Wodpress 可能就要先設計好了,database 與 storage 都要掛在他們的雲服務上,這樣才不會有誰不能關機的問題。這算是一個實驗性的文章,但負載平衡這種東西,在工作上也是挺有用的,算是又學到了樣新東西吧。

Leave a Reply