阿里雲搭建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就沒有這麼便利了。


最終架構如上所示。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章