整个过程经历了从“解决报错”到“建立隧道”再到“全自动镜像更新”的完整进化。
第一阶段:解决同步后的 500 报错
背景: 使用 rsync 从西雅图同步了文件,但南京站无法打开,返回 HTTP 500 错误。
- 病因: 西雅图站开启了 Redis/Memcached 缓存,同步过来的
object-cache.php在南京站因为缺少对应的 PHP 插件和 Redis 服务而导致崩溃。 - 操作: 重命名了缓存引导文件:
mv wp-content/object-cache.php wp-content/object-cache.php.bak。 - 修正数据库用户
wpuser的权限。
第二阶段:环境差异化配置
背景: 西雅图和南京的访问环境不同(SSL 证书、数据库密码、域名)。
- 操作: 在南京站的
wp-config.php顶部添加了$_SERVER['HTTPS'] = 'on';欺骗 WordPress 识别 HTTPS(解决 Cloudflare 中转导致的重定向循环)。 - 在
wp-config.php中硬编码WP_HOME和WP_SITEURL确保南京站访问。
第三阶段:编写自动化同步脚本
背景: 需要一个能每天自动对齐两地数据,且不破坏南京站本地配置的方案。
- 脚本逻辑:
- 远程备份:通过 SSH 在西雅图执行
mysqldump。 - 拉取数据:使用
rsync将.sql文件和wp-content拉取到南京。 - 增量同步:使用
--exclude参数排除了wp-config.php和缓存文件,防止覆盖南京本地配置。 - 自动修复:引入
wp-cli工具,在同步后自动执行wp search-replace,将数据库里的西雅图域名全局替换为南京域名。
- 存放位置:
/usr/local/bin/sync_wp_from_settle.sh。
第四阶段:解决跨国网络与备案 (Cloudflare Tunnel)
背景: 南京机器没有公网 IP 或受限于 80/443 端口备案拦截。
- 方案: 使用 Cloudflare Tunnel (cloudflared)。
- 操作:
- 在南京机器安装
cloudflared。 - 通过
cloudflared tunnel login进行身份认证。 - 创建了隧道
nj-tunnel,并生成了对应的凭证。 - 编写了
config.yml配置文件,将隧道映射到本地 Nginx 的 80 端口。 - 配置了 Origin Rules 或 DNS 路由,让用户访问
api.yourdomain.com时通过加密隧道直达南京机器。 - 将隧道注册为系统服务:
sudo cloudflared service install,实现开机自启。
第五阶段:最终自动化闭环
背景: 将所有步骤串联,实现无人值守运行。
- 操作:
- SSH 免密:配置了 RSA 密钥登录,确保脚本执行时不卡在密码输入环节。
- 定时任务:在
crontab中设置了每天凌晨 3:00 自动运行同步脚本,并记录日志到/var/log/wp_sync.log。 - 域名适配:解决了
wp-cli在命令行运行时因缺少HTTP_HOST产生的警告,通过在wp-config.php增加PHP_SAPI判断来优化。
当前系统架构清单
- 西雅图主站:源数据提供者,通过 Tunnel 连接 Cloudflare。
- 南京镜像站:通过内网穿透(Tunnel)对外服务,无需备案端口。
- 同步机制:
- 文件:Rsync 增量同步(排除配置文件)。
- 数据库:每日覆盖导入 + 域名实时转换(
wp-cli)。
- 访问入口:
- 全球流量 ->
yourdomain.com-> 西雅图。 - 国内/镜像流量 ->
cn.yourdomain.com-> 南京。
维护
- 日志监控:定期检查
/var/log/wp_sync.log确保每天的Replacements统计正常。 - 空间管理:脚本末尾建议保留
rm -f /tmp/wp_sync.sql以防磁盘占满。 - 插件同步:如果在西雅图安装了需要特殊配置的插件(如 Redis 缓存),在南京站手动处理对应的
exclude逻辑。
架构充分利用了 Cloudflare 的边缘能力解决了复杂的跨境网络问题!