手上的树莓派要物尽其用,折腾了一个多星期终于实现了typecho下的动静资源分离和RPI/CentOS的双机热备。期间踩了很多巨坑,在此记录一下。

相关环境

  • 主服务器CentOS
  • 加速服务器Raspberry Pi 3B+
  • 域名解析商Dnspod
  • 服务器均为静态IP,没有封端口等情况
  • 服务器环境均已搭建好LNMP
  • 所有服务器操作均为root用户登录

需求简介

  1. 主服务器保存所有资源和数据库,解析static.imwxz.comwww.imwxz.com域名
  2. 加速服务器保存静态资源,解析static.imwxz.com域名
  3. 国内用户仅将static.imwxz.com域名解析到加速服务器,国外用户均解析到主服务器
  4. 主服务器稳定。加速服务器不稳定,会遇到断电、断网的情况,如果宕机则自动解析到主服务器
  5. 静态资源需要在两服务器间单向同步(主=>加速),由于是博客网站,静态资源修改较少和服务器配置等原因,仅需做到新增资源实时访问,所有修改延时同步即可。

网络结构图:
Drawing1.png

为什么不使用反向代理?
虽然反向代理配置起来比较方便但是由于DDOS防护,限制了并发数和连接数,虽然有缓存但是在访问不存在资源大量回源时加速服务器被屏蔽,而如果加入白名单又会占用大量资源,得不偿失。

DNS解析设置

至于为什么用dnspod唯一的优势就是可以免费且不用很麻烦的认证就可以使用D监控和分流解析,之前cloudxns非常不错速度飞起,但是在17年被公安查水表之后就需要实名认证了,其实认证也没啥关键是它的认证异常麻烦要给一堆信息还要拍手持身份证照,再加上那次是直接停止解析没有任何通知,让人对这公司的信誉产生疑问,故放弃。虽然dnspod现在速度玄学但是能用,也就忍了。

主机记录记录类型线路类型记录值
wwwA默认主服务器IP
@A默认主服务器IP
piA默认加速服务器IP
staticCNAME国内pi.imwxz.com
staticCNAME国外www.imwxz.com
static-baseCNAME默认www.imwxz.com

关于static-base记录的作用下面再讲

这样设置以后就实现了解析分流了,然后再给static域名加上D监控,设置宕机时切换就行了。

rsync同步设置

rsync是一个很出色的目录同步软件,但是我在使用时遇到了大坑,请仔细阅读。
rsync分为服务端和客户端,有两种配置方法,一种是把主服务器作为客户端,加速服务器作为服务端,另一种则反过来,两者各有优缺点。

①主服务器作为客户端主动推送

如果对同步性要求不高不推荐此方法。

优点:可以配合inotify实时同步或sersync实现增量实时同步
缺点:如果要拓展每台服务器均需要配置,加速服务器宕机会造成推送出错

加速服务器端配置

  1. 防火墙放行873端口或者关掉

  2. 安装rsync

     apt-get install rsync
    
  3. 拷贝示例配置文件到/etc目录

     cp /usr/share/doc/rsync/examples/rsyncd.conf /etc/
    
  4. 修改配置文件

     vim /etc/rsyncd.conf
    

    参考配置

     uid = root
     gid = root
     use chroot = no
     max connections = 4
     pid file = /var/run/rsyncd.pid
     exclude = lost+found/
     transfer logging = no
     timeout = 900
     ignore nonreadable = yes
     dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
     hosts allow = 主服务器IP
     hosts deny = *
     
     [static]
         path = 网站目录
         exclude = .well-known/ .user.ini
         read only = false
         write only = true
    
  5. 认证设置

    如果您的服务器SSH不允许通过密码登陆(PasswordAuthentication no),您将不能使用rsync的密码认证,必须使用无密码证书认证

这是我通过多次试验发现的,网上没找到任何资料……因为rsync使用ssh作为传输端口,如果你的服务器SSH连接关掉了密码登陆只允许证书登陆(即sshd_config设置PasswordAuthentication no),那么你在推送文件时开始并不会出现任何问题,但是会在最后给出一个诡异的错误:

1
2
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(226) [sender=3.1.2]

文件自然是没有同步了,而且这个错误网上资料很少,我也是在偶然情况下想到或许是这个原因(草草草草草)解决办法要么是打开密码登陆,要么使用证书登陆,使用rsync的密码认证见下节,本节我用证书登陆举例。
这里的证书和SSH证书登陆的证书是相同的,相信如果你选择这种方法一定已经有登陆证书了,直接用就行,最好不要加二次验证密码,当然也可以重新生成一个,.ssh目录下authorized_keys里面换行就可以添加多个公钥。

务必保证您赋予证书登陆的用户拥有待同步目录的操作权限,因为后面客户端主动推送实际上就是通过这个用户权限操作的。

  1. 开启rsync服务

     vim /etc/default/rsync
     RSYNC_ENABLE=false => RSYNC_ENABLE=true
    
     rsync --daemon
    

主服务器端同步测试

务必执行此项测试,第一次连接需要手动确认。

需要将SSH登陆私钥拷贝到服务器上,假设目录为/root/.ssh/private,待同步目录均为/www/static.imwxz.com/,用户为root

rsync -aHzL -e "ssh -i /root/.ssh/private" --exclude={.well-known/,.user.ini} --delete /www/static.imwxz.com/ root@加速服务器IP:/www/static.imwxz.com

然后输入yes,如果没有什么问题就可以在加速服务器的/www/static.imwxz.com下看到同步的内容了。

②加速服务器作为客户端主动拉取

如果对同步性要求很高不推荐此方法。

优点:只需要配置一次服务器即可,方便添加节点
缺点:不能实时监控文件修改,只能定时更新

主服务器端配置

参考上节中加速服务器端的配置,注意修改配置文件中的许可IP,并且需要把read onlywrite only配置的truefalse互换。

这里奇怪的事情就出现了,仅仅拉取似乎并不受SSH的限制,rsync的用户密码验证在这里是可以生效的!

添加密码验证需要在/etc/rsyncd.conf的相应节中添加

auth users = 用户名(与系统用户无关)
secrets file = /etc/rsyncd.pass

然后新建密码文件

vim /etc/rsyncd.pass

文件格式为用户名:密码,用户名需要和auth users对应
注意这个文件必须是root所有且为600权限,修改权限

chmod 600 /etc/rsyncd.pass

加速服务器端同步测试

假设配置文件中节名为static,待同步目录为/www/static.imwxz.com/

rsync -aHzL --delete --exclude=".user.ini" user@主服务器ip::static /www/static.imwxz.com/ --password-file="/etc/rsyncd.pass"

这里的user就是服务端auth users配置的用户名

可以看看/www/static.imwxz.com/目录,是不是已经同步成功了?

计划任务定时同步

这个好办,加上计划任务就行,我这里直接在面板上添加shell脚本定时24小时执行一次就行了。

nginx 404回源

刚才的同步只是满足了修改延时更新的要求(对于博客网站碰到这种情况不多),万一我新上传了一张图片难道还要等一天才能看到么?显然这是不行的,这里我用了一个小trick就实现了这个功能。
nginx配置中可以修改404页面的指向,我们在DNS解析设置的static-base记录就派上用场了,我们将它和static解析到同一个目录,然后设置加速服务器nginx

error_page 404 https://static-base.imwxz.com$request_uri;

即出现404就指向主服务器(其实也就是主服务器的static.imwxz.com,因为直接写会出现循环重定向,所以我们就换一个名字),这样如果新增了一个文件没有被同步到,就会自动跳到主服务器的相应位置。

typecho动静态分离

说实话typecho这一点做的就没有wordpress好了,没有现成的插件可以用,不过我用的主题自带了主题文件分离,下面需要做的就是把upload文件夹分离出去就行了(其他主题可以照此同理)
其实方法很简单,在主服务器static网站目录建立一个软连接就行

ln -s src dest

因为上文rsync有-a选项,同步的时候会把upload目录一起同步过去,而且软连接还有一个好处就是不用修改上传的代码或者用其他插件了。

最后就是把所有附件地址替换为static.imwxz.com开头的就可以啦~这里可以用nginx的replace-filter-nginx-module模块,不过有人已经做好了typecho的插件,我们直接用就可以了。

下载TEDUriReplace插件