1. 程式人生 > >阿里雲搭建wordpress生產級CMS網站實踐

阿里雲搭建wordpress生產級CMS網站實踐

搭建cms內容站點時,wordpress是一個很好的選擇,不用做任何開發就可以通過配置、外掛獲得豐富的功能。用docker容器技術部署運維都非常簡單,特別是對於wordpress這種我們無需做任何開發的元件。而出於低成本考慮,公有云都是一個最佳選擇,這裡我選擇阿里雲。為了提速,wordpress前會有一個nginx作為負載均衡和web加速伺服器,將靜態內容都由nginx處理。出於高可靠性,我選用阿里雲的容器服務(目前免費),由它來管理所有容器。而多容器間的磁碟目錄共享,阿里雲提供了oss對映和nas盤,oss盤的速度太慢,而nas盤IO與雲盤相當,可以作為第一選擇。資料庫為了可靠性,如果沒有獨立的DB運維人員,就選擇rds mysql好了(目前單機版RDS剛上線,相比雙機mysql便宜很多)。

一、最初我們驗證方案時,總是先從最簡單的做起,功能滿足要求即可。

1、我們購買好ECS(如果是經典網路一定要含公網頻寬,否則接下來用到阿里雲容器服務時你會悲催的發現,目前阿里雲容器要求叢集內的經典網路節點必須含有公網頻寬, 否則該ECS無法加入叢集中。VPC網路就沒有這個問題。在可見的一段時間內,阿里雲可能都不會修復這個問題。),作業系統如果是centos7.0或者7.2,高核心版本支援docker就更簡單了。

2、資料庫在centos7.0以上版本時,mariadb比較方便(出於效能考慮,docker容器的db不推薦為生產環境下的資料庫)。yum install這個資料庫,修改/etc/my.cnf,使其支援utf-8,例如:

[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

用service mariadb start啟動資料庫。

2、用create user命令建立好使用者,create database建立好db,grant命令賦予許可權,例如:

create database yourdb;
CREATE USER youruser IDENTIFIED BY 'yourpass';
GRANT ALL PRIVILEGES ON yourdb.* TO youruser;
flush privileges;

3、用docker pull wordpress命令拉下官方最新版本的image,然後用docker run將其啟動。-p埠對映到主機的80埠上。注意,很多image都會通過提供環境變數來修改配置,而wordpress也是如此,這裡我們主要是修改其連線哪個資料庫,通常這四個環境變數配置好即可。

-e WORDPRESS_DB_HOST=... 
-e WORDPRESS_DB_USER=... 
-e WORDPRESS_DB_PASSWORD=... 
-e WORDPRESS_DB_NAME=... 

4、接下來我們將購買的域名在阿里雲的雲解析頁面上,配置到該公網IP上。(wordpress裡需要配置域名,直接使用域名比IP方便)。

5、在頁面上開啟域名,顯示wordpress的安裝站點頁面。根據提示傻瓜化的安裝這個wordpress,接下來我們就可以體驗下wordpress強大的CMS功能了。

二、接下來,我們需要一個更美觀的站點,而wordpress提供主題自定義功能。我們可以在google上找到很多免費或者收費的主題。接下來美化這個站點,使之符合功能需求。

1、首先找到符合要求的主題,下載後一般是一個zip檔案。

2、在wordpress的/wp-admin頁面下進入管理介面,由外觀->主題->新增->上傳主題頁面裡,點選選擇檔案,將zip主題包上傳。

通常在這個步驟中,我們可能會看到上傳失敗的結果。提示上傳檔案過大(特別是你下載的zip主題包達到幾十M的時候)。這是php服務預設允許的上傳檔案過小所致。要想解決,首先得改image的配置。此時,我們首先要重新執行docker,把容器的/var/www/html目錄對映到主機目錄中(用-v 主機目錄:容器目錄,這個volumes命令可以把容器的磁碟內容對映到主機目錄中供我們修改)。我們在對映目錄下建立.htaccess檔案,在此檔案中輸入以下配置項:

php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_execution_time 300
php_value max_input_time 300

這裡把上傳檔案的大小增加到64M。

再啟動docker容器,上傳並安裝新主題即可。

三、接著,多半會發現這個站點太慢了,體驗很差,我們希望網站速度更快一點。

1、用瀏覽器的debug模式可以發現,最慢的請求從url看都是獲取gravatar頭像,請求之所以慢與牆有關(提供頭像服務的機器網路不穩定)。最簡單的解決辦法是在wp-content/themes/your-theme-using目錄下,在functions.php檔案的結尾加上以下幾行(參見http://www.dmeng.net/wordpress-replace-gravatar-host.html):

function dmeng_get_https_avatar($avatar){
    $avatar = str_replace(array("www.gravatar.com", "0.gravatar.com", "1.gravatar.com", "2.gravatar.com"), "secure.gravatar.com", $avatar);
    return $avatar;
}
add_filter('get_avatar', 'dmeng_get_https_avatar');


2、增加一臺nginx,域名直接指向nginx所在的機器,由nginx將動態請求反向代理給wordpress容器。而靜態內容由nginx處理。

此時我們可能會遇到網站無法訪問的情況,在nginx的日誌裡可以看到是301重定向過多導致。解決辦法還是在上面的functions.php檔案的結尾加上一行:

remove_filter('template_redirect', 'redirect_canonical');


我們還可能遇到上傳新的主題檔案時得到413錯誤,這是nginx拒絕所致,記得在nginx.conf里加上client_max_body_size 60M;

3、nginx還可以配成http2,但後面得用阿里雲的slb防單點。

四、一臺訪問速度和功能都滿足我們需求的CMS站點出現了,接下來,我們開始解決可靠性問題。首先,我們需要把單點資料庫改為RDS資料庫(如果你的資料庫有人全職維護那就不需要)。購買一個rds例項,建議與你的ECS在同一個可用區(同一機房內,頻寬高又穩定)。目前RDS單例項對於使用wordpress作為站點的公司來說應該夠了吧?

1、在web站點上初始化root使用者密碼(注意,阿里雲的RDS使用者許可權比自建的小了很多!)。

2、加上訪問白名單。通常我們是ECS內網訪問資料庫(便宜安全),所以將ECS內網IP加入白名單。

3、遷移資料。這裡我悲催了,阿里雲RDS提供的遷移工具只能是mysql對mysql遷移,而我之前用的是相似的mariadb,遷移工具執行失敗,提工單後售後反饋暫時不支援。

不同種類資料庫的遷移這種情況下,用sql匯入肯定是可行的。於是準備用mysqldump把mariadb中資料庫的資料匯出sql檔案,出現錯誤:

mysqldump: Error: Binlogging on server not active

在my.cnf上加入

log_bin=mysql-bin

再執行:
mysqldump --databases yourdb --user=youruser -hyourhost --password --master-data > transfer.sql

先用root登上RDS,建資料庫建使用者。再匯入時發現還是不行:

ERROR 1227 (42000) at line 22: Access denied; you need (at least one of) the SUPER privilege(s) for this operation

這是生成的sql檔案裡有RDS不支援的操作。將其中最上面的兩行刪掉:

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=191500;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `yourdb` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */;

再執行:
mysql -u youruser -h yourhost yourdb -p < transfer.sql

即完成資料庫的遷移。

4、最後將docker wordpress容器通過環境變數指向RDS資料庫。

五、資料庫單點解決掉後,再來解決wordpress container容器的單點與運維。這裡有個待解決的問題是wordpress容器如果有多個例項,且跨ECS主機,那麼就需要共享磁碟去對映容器中的/var/www/html目錄(特別是其中包括uploads上傳檔案的目錄)。

1、首先,我們要利用阿里雲容器將dockoer容器運維起來的優勢,將wordpress放在容器服務裡執行。

2、其次,阿里雲容器支援OSS或者NAS盤對映到叢集內每一臺ECS機器上某個目錄。即,如果我們配置資料卷支援OSS和NAS(當然需要先購買這兩種服務),叢集內每個ECS都將自動的多出/mnt/acs_mnt/nas和/mnt/acs_mnt/ossfs目錄,方便我們每個contain容器進行對映。

這裡需要注意,如果是oss對映為磁碟,必須在其他引數裡增加“-o umask=000",否則docker容器每次新生成的檔案其許可權是有問題的,無法訪問,這個BUG阿里雲可能以後會解決吧。

另外,大家會強烈的感受到用oss去對映/var/www/html目錄網站就會非常慢,這是因為oss本身的時延就高,而改成nas盤就會好多了。(但oss盤比nas盤便宜很多)

當然,用oss可以非常方便的使用cdn,nas就沒有這麼便利了。


最終架構如上所示。