【案例分享】如何利用京東雲建設高可用業務架構

語言: CN / TW / HK

作者:京東雲 張久志

本文以2022年一個實際專案為基礎,來演示在京東雲上構建高可用業務的整個過程。公有云及私有云客戶可通過使用京東雲的彈性IAASPAAS服務,建立高可用、高彈性、高可擴充套件、高安全的雲上業務環境,提升業務SLA,提升運維自動化水平,降低資源成本及運維成本。有業務遷移上雲需求,希望構建雲上高可用業務架構的客戶或對雲上高可用架構規劃有興趣的讀者可以一看。

客戶業務為典型的web應用,在京東雲上建立一個通過公網IP/域名訪問的高可用的web網站,包含通用應用的標準框架,包括訪問接入層、APP層、快取層、資料庫層。整體業務架構設計提供可用區(AZ)級別的高可用等級。

本文演示場景包括AZ出現故障導致的主機故障、資料庫故障、快取故障場景下,業務能夠提供持續訪問能力。並保障資料的完整性和一致性,同時,能夠在無人干預的條件下,實現業務的彈性擴充套件,保障業務高併發的場景下有良好的響應時間。

說明:

本文的架構為演示架構,並未嚴格遵循生產環境的業務效能及安全的整體規劃步驟及要求,在生產環境中,至少應該對主機及CFS的儲存效能進行壓測,確保能夠滿足實際業務需求,同時,通過域名訪問的web服務,建議使用WAF等安全防護產品,保障業務的入口安全。

1、京東雲高可用架構設計

業務架構以某單位的業務需求為基礎,模擬其業務生產環境,規劃京東雲上的業務整體架構,其中,  NAT閘道器、負載均衡、堡壘機均建立在公網訪問子網,其餘主機及資料庫等,建立在內部子網內。

其中應用主機使用高可用組建立, LB後端直接掛載高可用組。

使用高可用組的目標是實現業務高峰期故障時,計算資源能自動加入負載均衡後端,自動化擴充套件業務處 理能力。減少運維干預成本

2   資源需求(所有IPURL均調整為非真實IPURL

專案

規格

數量

說明

 

主機

2C8G 50G系統盤

2~3

為保障驗證效果,主機能臨時繫結公網IP  (生產環境無需綁 )  100.126.38.2  ()  10.0.1.16 100.126.38.3  ()       10.0.1.13  10.0.1.16 演示過程中會有新主機生成

 
 

高可用組

使用應用主機 模板

1

配置彈性伸縮,配置告警條件,在業務壓力大導致CPU觸發 閾值後,自動擴容主機,提升負載能力

 
 

資料庫

2C8G  50GSSD 儲存      MySQL   5.7

1

mysql -1-a0b7e160c1xxxx.jdcloud.com

 
 
 

Redis

4G

1

redis-1kn4b5zwgzc5-xxxn-1.jdcloud.com

 

公網IP

4個,主機及LB各一個

4

5M頻寬

 

LB

1個,配1個公 IP 作為業務 入口

1

LB繫結公網IP,配置輪詢模式。例如,  Vip  10.0.1.27 公網 IP  100.126.35.4

 
 

CFS

1

1

共享儲存作為業務應用資料儲存目錄掛載於高可用組主機特 定目錄下:例如,  mount -t nfs -o vers=3 -o noresvport     10.0.0.200:/cfs /wp

 

3應用部

3.1 基礎環境準備

業務以一個典型的wordpress的網站為例,業務容器化部署於雲主機上,高可用依賴京東雲的雲主機高可用組,主機安裝docker,並配置docker服務自動啟動。

 

#建立應用資料目錄 配置目錄許可權、安裝docker等

 mkdir -p /wp

 chmod 777 /wp

 yum install docker vim -y

 systemctl enable docker

 systemctl start docker

 #掛載CFS檔案作為應用資料目錄

 yum install nfs-utils -y

 systemctl enable rpcbind    

 systemctl start rpcbind

 mount -t nfs -o vers=3 -o noresvport 10.0.0.200:/cfs /wp

#配置啟動自動掛載CFS及啟動服務,通過rc.local實現:

#[root@wpha0 wp]# cat /etc/rc.local

#!/bin/bash

# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES

#

# It is highly advisable to create own systemd services or udev rules

# to run scripts during boot instead of using this file.

#

# In contrast to previous versions due to parallel execution during boot

# this script will NOT be run after all other services.

#

# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure

# that this script will be executed during boot.

touch /var/lock/subsys/local

mount -t nfs -o vers=3 -o noresvport 10.0.0.200:/cfs /wp

#(說明,生產環境可在/etc/fstab掛載)

bash /root/start.sh

start.sh見以下程式碼

[root@wpha0 wp]# cat /root/start.sh

docker stop wordpress

sleep 3

docker rm wordpress

sleep 3

docker run -d --name=wordpress --restart=unless-stopped -p 443:443 -p 80:80 -v /wp:/var/www/html wordpress

#[root@wpha0 wp]#

#啟動指令碼編輯完成後,並寫入rc.local後,rc.local調整成可執行,以實現啟動主機執行指令碼, rc.local實現了主機啟動後自動掛載CFS到指定目錄,然後,通過start.sh自動清除舊資料,重新拉起wordpress服務。

chmod +x /etc/rc.d/rc.local

#拉取應用所需映象

 docker pull wordpress

#拉取映象後,執行服務。

docker run -d --name=wordpress --restart=unless-stopped    -p 443:443 -p 80:80  -v /wp:/var/www/html  wordpress 

意,這個場景下,主要調整了幾個位置:

1、掛載CFS為wordpress的工作目錄,這樣,調整頁面內容以及拉起新主機後,網站內容都保持一致。相關自動掛載方式為在/etc/rc.local加入掛載命令,同時chmod +x /etc/rc.d/rc.local 把這個檔案加一下可執行許可權。

2、需要把wp目錄的許可權改為777 (或docker內部的 33 tape等,不過不同版本可能有區別,改成777相對穩妥), 否則掛載後,docker內部的wordpress無法獲取目錄讀寫許可權。

3、NFS掛載需要安裝nfs外掛 yum install nfs-utils -y 並啟動rpc服務 systemctl enable rpcbind   systemctl start rpcbind

WP目錄為777 許可權

 

到這裡基礎主機環境準備完成。

下一步,wordpress應用的配置,實現高可用視覺化的演示效果。

3.2業務側 wordpress配置

web應用使用wordpress部署。通過docker部署,並實現高可用組主機自動伸縮自動化拉起。

通過docker拉取wordpress

docker pull wordpress

拉取映象後

docker run -d --name=wordpress --restart=unless-stopped    -p 443:443 -p 80:80  -v /wp:/var/www/html  wordpress

其中/wp 是掛載的CFS,作為多個應用主機共同掛載,作為wordpress的應用的應用檔案目錄。

啟動wordpress容器,並掛載CFS目錄為WP的應用目錄。

以上部署在3.1中已經完成。

 

前置準備工作-負載均衡:

配置一個帶公網IP的負載均衡,並配置監聽器,監聽器後端暫時配置一個已經拉起了docker的這臺主機

 

前置準備工作-資料庫:

在配置網站前,需要首先在雲控制檯的RDS那裡為wordpress建立一個賬戶:wordpress,並設定密碼,建立一個庫:wordpress(因為後續演示方案有調整,我又建立了一個新庫wordpressbackup,實際正常來講一個庫就可以了),並授權wordpress庫給wordpress使用者。

 

前置準備工作-redis:

在控制檯購買一個redis,記錄redis的URL,為後續配置redis 快取做準備。

這樣,基本的應用環境就緒了。

通過覽器訪問負載均衡(注意訪問LB,不直接訪問主機)IP80埠,即可進入wordpress的配置 面, wordpress的配置,主要是資料庫的地址以及資料庫字首的配置,輸入正確的資料庫的host 地址及密碼即可,其餘保持預設,其他依據官網手冊指導保持預設配置即可。

配置完成後,wordpress自動為網站建立相關的表,並提示配置wordpressadmin以及管理密碼。

安裝完成後,可以登入資料庫檢視建立的表,後續MySQL高可用演示時,也可以登入到資料庫做些 操作,不受高可用切換影響。

到此,基本的應用就安裝完成了。

redis動態快取加速:

redis的角色,在這個案例裡邊,在wordpress redis 作為一個動態加速快取使用,對加速網站訪問, 減輕資料庫壓力起到一定作用

下載wordpressredis外掛,redis-cache

下載後通過wordpress的管理頁面-plugin --addnew 直接上傳,然後依據外掛操作手冊安裝配置即可。

安裝redis-cache以後,會在/wp/wp-content/plugins 目錄下生成一個 redis-cache目錄。需要同時在/wp/wp- content 下生成一個 object-cache.php檔案,正常來講,需要調整一個引數host改成redis的域。如果配置了密碼,就需要調整這個以及redis-cache目錄下的配置檔案把密碼配置進去,這個因為是 演示環境,redis設定 了免密,生產環境一定要設定密碼。

安裝配完成後,在管理介面的setting裡會有redis的配置選項,這個和版本有關係,有些版本可能會讓 在這裡做引數配置。直接改檔案參數效果是一樣的。

mysqlredis管理及相關登入方式介紹:

MySQL的登入,沒有安裝client,使用了一個mysql的docker

相關命令:

docker run --name mysql -p 3306:3306  --restart=unless-stopped -v /root/dbackup/:/db -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

進入mysql的docker中:

docker exec -it mysql bash  

連線wordpress使用的資料庫:

mysql  -h mysql-xxxea04fc4c52.jdcloud.com -u wordpress -p

use wordpressbackup;

show tables;

select id from wpbackup_posts;

 

--中間因為做了多次演練和資料庫切換,中間做了wordpress資料庫匯出和匯入操作

mysql 資料庫匯出(均在mysql的docker容器中執行命令):

mysqldump  -h  mysql-xxxa04fc4c52.jdcloud.com -uwordpress -p --databases wordpressbackup >/db/wordpressbackup-0322.sql

資料匯入:

進入資料庫,

use wordpressbackup;

source /db/wordpressbackup-0322.sql;

 

----redis驗證

redis驗證,同樣是沒有安裝client,通過docker裡的命令列去連線:

docker run -d --name redis --memory=1G -p 7379:6379   redis

docker exec -it redis bash  

 

redis-cli -h redis-j49rpxxx.jdcloud.com

 

登入後,檢視資訊:

KEYS *

 

wordpress置主頁顯示hostname及來源IP

---wordpress獲取hostname 在頁面展示+獲取訪客地址,以增強演示效果,明確看到訪問的實際主 位置。

為了讓訪問者看到訪問IP是哪個(證實高可用組的自動擴容及業務的自動拉起),需要在所使用的 theme 目錄的function里加入相關程式碼。  /wp/wp- content/themes/twentytwentytwo/function.php

[root@AG-wordpress- HA-group1-c8705-2 twentytwentytwo]# vim /wp/wp-content/themes/twentytwentytwo/function.php

在裡加入以下程式碼,一個是show_ip函式,一個是show_hostname函式。

function get_the_user_ip() {
if ( ! empty( $_SERVER["HTTP_CLIENT_IP"] ) ) {
//check ip from share internet
$ip = $_SERVER["HTTP_CLIENT_IP"];
} elseif ( ! empty( $_SERVER["HTTP_X_FORWARDED_FOR"] ) ) {
//to check ip is pass from proxy
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
} else {
$ip = $_SERVER["REMOTE_ADDR"];
}
return apply_filters( "wpb_get_ip", $ip );
}
add_shortcode("show_ip", "get_the_user_ip");

function get_hostname()
{
     $hostname = gethostname();
          echo "$hostname\n";
      return apply_filters( "hostname", $hostname );
}

add_shortcode("show_hostname", "get_hostname");

 

然後,在wordpresssite加入短程式碼實現:

儲存後看到頁面可以顯示相關的IPhostname資訊了。

到這裡,  wordpress的應用環境配置完成。

下一配置業務的高可用環境,實現跨AZ的高可用組及主機自動彈性伸縮。

3.3 例項模板及高可用組、LB配置

單臺主機配置完成後,重啟能自動拉起應用,進行確認後, 將現有主機打一個映象。作為高可用組的例項模板。後續LB端的高可用組通過這個模板建立主機。

其餘包括資料庫配置、網站資料、redis快取配置等,均實現了服務及資料的分離,因此,在後期進行動 態彈性擴容時,使用這個模板的高可用組,可以直接拉起服務,實現動態彈性伸縮

例模板:

可用組:

高可用組使用作好了wordpress的應用主機的映象。做到高可用組自動彈性伸縮出新主機--新主機自動 拉起wordpress--新主機自動掛載到LB接收業務流量的模式。

LB配置。

LB器選擇後端服務為高可用組,並配置健康檢查。

 

高可用組掛載到LB後端以後,應用環境已經搭建完成

可以訪LB入口,訪問到網站,並且會輪詢到不同伺服器,同時,訪問單臺伺服器的外網IP 也可以訪問站業務:

LB問截圖(2張,分別訪問到了兩個主機)

單臺主機訪問截圖(直接訪問單臺主機IP,重新整理後不會輪詢主機):

演示環境就緒。

下一步,進行破壞性演練,檢驗高可用環境的效果。

4、應用演示

高可用演示指令碼:

驗證專案

詳細描述

預期結果

 
 

雲主機

模擬主機故障- 通過底層命令/控制檯關閉可用區A的應用雲主機

站點訪問正常,可以新增、刪除、修改post

 

高可用組

高可用組配置彈性伸縮,設定最小最 大例項個數,並配置伸縮觸發的閾值  (告警配置內配置)

通過stress命令模擬高併發場景,高可用組通 過彈性伸縮特性建立新主機並掛載到LB後,實現多主機接收流量

 

RDS

模擬RDS例項故障- 通過底層命令關閉 RDS的主例項

- 主從切換,業務不受影響

 

RDS

主從切換從控制檯可以看到切換過程

切換過程完成後,  RDS狀態為執行中

 

Redis

模擬Redis例項故障- 通過底層命令關 Redis的主例項

- 主從切換,業務不受影響(本文未截圖)

 

Redis

redis在模擬故障過程中,業務持續訪

redis返回的資料不受切換影響(本文未截圖)

 

 

高可用組息,目前LB後端掛載的為高可用組:

測試頁面信息(所有IP均為非真實IP):

業務入口(LB)   http://100.126.35.4/

高可用組單臺主機訪問入口目前為:

http://100.126.38.13/

http://100.126.38.16

主機的高可用及自動伸縮

演示所需的一些指令碼

一個是模擬生產環境,對業務主入口的LB持續訪問,這個在測試過程中,一直可以訪問到,不會中斷。

#!/bin/bash
#for ((i=1;i<=10;i++))
for i in {1..15000}
 do
curl 100.126.35.4
echo $i
echo $(date +%T)
sleep 3
  done

 

一個是模擬單機環境,對業主機入口的持續訪問,這個在測試過程中,當針對單機關機時,訪問會卡住

#!/bin/bash

#for ((i=1;i<=10;i++))

for i in {1..15000}

 do

curl 100.126.38.16

echo $i

echo $(date +%T)

sleep 3

  done

演示過程中,高可用組自動伸縮功能,能正常擴容出新的主機並提供業務訪

高可用組的自動伸縮,通過 stress模擬壓力

安裝stress後,直接執行(主機為2C):

stress --CPU 2

通過top命令可以看到CPU被打滿。

過2分鐘(高可用組伸縮策略配置的時間),高可用組會自動擴充套件一臺主機,並作為高可用組的一臺主機自動掛載到LB的後端,可在LB及主機介面看到自動擴容的主機。

在控制檯將一臺高可用組內主機關機,然後可見LB後端服務健康檢查發現掛載的高可用組一臺伺服器異常,高可用組如配置最小的主機數量,則高可用組也自動擴出一臺主機,繼續提供服務。在此期間,流量會轉發給後端正常主機,健康檢查異常的主機不再接收流量,業務訪問持續正常。

PAAS務的高可用:

本演示以MySQLredis研發在底層直接殺docker,然後業務訪問不中斷,控制檯上會出現主從切現象在這個過程中對業務的訪問不會中斷

雲資料庫及快取的破壞性操作,底層操作由研發操作。

底層進行RDS主備切換(killRDS主庫),業務訪問同樣不會中斷,研發提供截圖可以看到主從切換過程。

本文實際部署環境為京東為客戶搭建的私有云環境(JDSTACK),公有云與私有云為相同技術棧,搭建及驗證過程相似。限於篇幅,redis驗證部分及主機可訪問性指令碼結果未截圖,感興趣的讀者可自行在雲上通過本文指引過程搭建驗證。