WordPress高可用尝试:建立镜像站并利用CDN负载均衡记录

发布于 2016-02-20  4.29k 次阅读


一直有一个想法,就是尝试一下改变网站的架构。如今有两台阿里云服务器在我手里,利用寒假时间折腾了一番。

现在微晨风景的结构:

  • 前端:阿里云ECS x2 + 阿里云CDN
  • 数据库:放在两台ECS上,互为主从备份
  • 静态文件:七牛

实践中发现,多台服务器托管同一个网站的核心就是同步问题。我粗略的总结为下面几点,有相应需求的童鞋们可以拿去参考:

  1. cookies同步:通过绑定同一个域名、使用同样的网站程序就行。
  2. 文件同步:统一放置静态文件,比如所有的图片、css、js都放到cdn.wangchenyu.net.cn。
  3. 文章同步:连接同一个数据库、或者连接不同的数据库但是这些数据库之间做好同步。

对于https网站,还多了一个坑,就是

  1. 每台服务器都要配置https证书、配置文件要一样(这是自然)
  2. 不能启用证书缓存。

因为nginx中有一个缓存机制,如果启用了缓存那么nginx会记住这个客户端,但是因为有多台服务器所以其他服务器并没有记住,这样会带来一些‘不必要的麻烦’。我没记错的话应该是ssl_staplingssl_stapling_verify

吐槽一句,折腾期间因为wp-super-config插件和cdn的缓存给我带来了无数的坑,好在最后看见了胜利的曙光……

一、阉割登录、注册模块

使用cdn是一个好主意,但是如果页面需要注册、登录,那么就没法缓存了。如果每次cdn都要回源那就浪费了流量,形同虚设了。(如果有哪位大大有好的方法避免cdn对wordpress登录状态缓存欢迎赐教)所以我干的第一件事,就是改成了第三方评论。有哪些第三方评论?

  • 多说
  • disqus
  • 灯鹭
  • 畅言
  • 友言
  • 贝米
  • ……

disqus常常抽风,多说太丑了,其他的不太放心,最后使用了搜狐的畅言。为什么我放心的使用畅言?因为搜狐自己的搜狐体育、搜狐财经等用的就是畅言评论。

说句题外话,当我看到美团出了一个美团云的时候根本不屑一顾,心想他有什么优势和阿里云、腾讯云竞争?结果美团云工程师的一句话就把我说服了:“美团是在美团云上的,而淘宝天猫和支付宝不在阿里云上”。所以我一下子就觉得美团云是真靠谱、有竞争力的。(纯个人观点,不是有意给美团云做广告)

二、调教wordpress和dux主题

首先wordpress本身的“上传媒体”的功能肯定是得废,文章中的图片可以用链接,文章特色图片怎么办?(就是文章列表左侧的图片)在后台找了几个插件都不能用,想着应该是dux主题特殊。然后借鉴一下获取文章第一个图片为特色图片的方法:

首先在主题functions.php中添加下面一个函数:

function catch_first_image() {
 global $post, $posts;
 $first_img = '';
 ob_start();
 ob_end_clean();
 $output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content,$matches);
 $first_img = $matches [1] [0];
 
 if(empty($first_img)){
 $random = mt_rand(1, 10);
 $first_img='/wp-content/themes/dux/img/random/'.$random.'.jpg';
 }
 return $first_img;
}

然后修改./wp-content/themes/dux/inc/fn.php,找到_get_post_thumbnail函数,在大概463行处,把函数底部最接近return$html,原来是

$html = sprintf('<img data-src="%s" class="%s">', get_stylesheet_directory_uri() . '/img/thumbnail.png', $class);

改成

$html = sprintf('<img data-src="%s" class="%s">', catch_first_image(), $class);

也就是说,$html的值变成了catch_first_image()函数。再在./wp-content/themes/dux/img/random/中上传10张缩略图以备文章无图时使用即可。

三、配置两台服务器环境

谷歌一下,方案都是共享数据库。我于是想动用阿里云跟随ACE免费送的rds。因为服务器在青岛,结果测试了一下延迟还是比较明显的。于是想起来另一个方法,只要让这两台服务器的数据库同步(互为主从备份)就行了。详情见(待更新),数据库同步的问题解决以后大头问题就没了。

  1. 整站从服务器1上传到服务器2上
  2. 修改服务器2的wp-config.php的文件,数据库地址、用户名、密码都写服务器2上的数据库用户名和密码。
  3. 服务器1的wp-config.php文件中,数据库地址、用户名、密码是服务器1上的数据库信息。

因为两个数据库都是本地连接,可以保证最快的速度。又因为启用了互为主从备份,所以数据是一样的。
至此,服务器环境设置完毕。

到阿里云cdn后台添加域名为https://www.wangchenyu.net.cn,回源IP分别填写两台服务器的地址,然后在dns处修改解析。此时发现,邮件的MX记录和CDN的CNAME不能共存。我注册很多地方用的都是域名邮箱咋能不要了呢。所以咨询了CloudXNS的客服后解决方法如下:

CNAME记录和MX记录无法共存?

@的MX记录保留,使用A记录解析到某台服务器,在服务器上设置nginx的rewrite规则跳转到www上
www使用CNAME记录解析到阿里云cdn

注意:如果@设置301跳转,跳转到的地址是http://www.xxx.com的,则源地址必须是http://xxx.com,https无法访问。反之亦然。所以最好还是解析到自己的服务器上然后设置跳转规则。

附上nginx跳转规则:(添加在server块中)

if ($host != www.wangchenyu.net.cn) {
 rewrite ^/(.*)$ $scheme://www.wangchenyu.net.cn/$1 permanent;
}

这样非www.wangchenyu.net.cn都会跳转到www上

至此,还有一些小的细节比如https优化,需不需要七牛回源(七牛回源不支持https,可用nginx判断user-agent来确定是否跳转)之类的问题也解决了。

另外,用cdn加速以后百度可以抓取https页面了,终于不用针对百度蜘蛛写https和http的跳转规则了……