先简单说一下为什么这么做

首先我自己家里有一台NAS设备,并且在我软磨硬泡之下,运营商给开通了公网IPV4。通过DDNS解析,可以使用域名随时在外网访问家里的NAS,于是我在NAS上使用1panel部署了本站,数据库是使用的NAS上安装的MySQL,附件是使用的本地存储策略。走的是宽带的上行,50M的速度,比云服务器的小水管爽太多了。

但是运营商是屏蔽了80端口和443端口的,这就很不爽了!总是host+指定端口才能正常访问!于是我尝试了使用CDN,回源指定了端口,也可以实现去端口访问。但是长时间使用CDN无疑又是一笔支出,哪怕量不大,心里面还是有芥蒂。

在没有开通公网IPV4之前,我是用的frp内网穿透。为了使用内网穿透,我还买了两年的云服务器。开了公网之后,云服务器一直在闲置。所以我就想着,在云服务器上也部署本站。于是把NAS上的Halo数据备份,并且在云服务器上也部署了一份。

这里补充一下:

Nas上博客的访问链接:https://blog.imkka.cn:1080/

云服务器上博客访问链接:https://imkka.cn/、https://www.imkka.cn/

问题处理

到这里,有一个问题需要解决——在两台主机上,数据库、附件的同步问题。

因为云服务器配置只有2c2g,带宽4M。所以就没有在云服务器上部署数据库,云服务器上的Halo使用的是NAS的MySQL,也就是说,现在的云服务器、Nas的Halo站点,其实是用的同一个数据库。所以数据库同步的问题就不存在了。

那就只有附件的同步问题了。

尝试方案

我尝试过使用使用 Rsync 结合 Inotify,进行双向同步。在两台服务器上分别做一下配置:

  • 安装相关软件:在两台 Linux 服务器上分别安装 rsyncinotify。对于基于 Debian 的系统(如 Ubuntu),使用 sudo apt-get install rsync inotify-tools 命令安装;对于基于 Red Hat 的系统(如 CentOS),使用 sudo yum install rsync inotify 命令安装。

  • 配置 SSH 无密码登录:在两台服务器上分别执行 ssh - keygen - t rsa 命令生成密钥对,然后将各自的公钥复制到对方服务器,实现 SSH 无密码登录3

  • 编写同步脚本:在两台服务器上分别编写同步脚本。以下是一个示例脚本,把路径ip改一下就行:

#!/bin/bash
while inotifywait -r -e modify,create /var/www/html/blog # 监控博客文件目录的变化
do
    rsync -az -e ssh --exclude='.*' /var/www/html/blog/ root@对方服务器IP:/var/www/html/blog/ # 将变化同步到对方服务器
done
  • 赋予脚本执行权限:使用 chmod +x 命令为脚本赋予执行权限。

  • 运行脚本:使用 nohup 命令在后台运行脚本,使同步在服务器重启后仍能持续进行。

注:以上由豆包生成

所有的工作做完之后,我尝试着在其中一个站点的后台,上传了一个图片附件。经过观察两台服务器的Halo附件的upload的文件夹,确实都有了刚刚上传的图片。但是访问被同步的那台服务器的站点后台,同步过来的附件并没有在附件列表里。

我猜测是上传图片的时候,不仅仅是文件需要同步过去,可能还有内置的文件服务器需要做什么设置,又或者会在MySQL中插入数据(可能有人会有疑问:“你上面不是说用的同一个数据库吗?”,这里我补充一下:云服务器上的博客,是使用的1panel同步远程数据库的方式,连接了Nas的数据库,然后部署halo的时候选择了该远程服务器,不知道这种方式还是不是同一个库)。

算了,不猜了!换一种方式,曲线救国!

最终方案

由于我Nas上也部署了Alist,Halo刚好就有插件支持Alist存储策略。于是我云服务上重新部署了Halo,并且在docker启动命令手动指定了数据库地址,确保和Nas上的博客数据库是同一个。然后在Nas和云服务器的博客上安装并启用AList存储库,然后所有的附件全部存储到Alist存储策略中。奇怪的是,在Nas服务器博客后台上传了附件之后,云服务的博客后台同样看不到附件记录!不知道到底怎么回事,不过使用alist存储图片,哪怕附件记录中没有数据,也不影响正常显示(Alist有)。

下一步准备去扒一下源码,看看上传和查看附件列表的接口到底做了什么。

至此,充分利用了Nas设备的性能,云服务器只保持低负载运行。两个Halo站点不完美同步!