上个月我把一台 Hetzner 独服上的 50 多个网站迁移到新服务器,要求零停机。这篇文章记录完整方案。
为什么不能直接 rsync 一把梭
从打包到 DNS 生效中间有几十分钟窗口期,用户可能在写数据。DNS TTL 也让切换时间不可控。
三步方案
第一步:预同步
rsync -avz --exclude 'cache/' --exclude 'tmp/' /home/wwwroot/ root@new-server:/home/wwwroot/旧服务器运行时做,不影响服务。
第二步:增量同步 + 数据库
rsync -avz --delete /home/wwwroot/ root@new-server:/home/wwwroot/
mysqldump -u root --all-databases --single-transaction | ssh root@new-server 'mysql -u root'第三步:切换流量
- 新服务器 Nginx 反向代理回旧服务器
- 先切一个不重要的站点验证
- 确认后批量切换 DNS
Cloudflare 优势
CDN 缓存充当缓冲层,切换对用户完全透明。
踩过的坑
- 数据库地址改 127.0.0.1 而非外网 IP
- PHP 版本不一致导致老插件报错
- 文件权限 UID 不同需单独 chown
- SSL 证书别忘了一起迁移
总结
零停机核心是"重叠运行"。rsync + mysqldump + Nginx 流量调度,用户甚至不知道你搬了家。