云服务器跨厂商迁移怎么尽量不停机:用 rsync、MySQL binlog 和 DNS TTL 做双阶段切换

更换云服务器时,真正困难的通常不是把文件复制过去,而是如何处理迁移期间仍在发生的写入:用户上传了新图片、订单状态改变、数据库又产生了增量数据,而 DNS 缓存中的旧 IP 还没有完全失效。如果只做一次全量拷贝再改解析,很容易出现文件缺失、数据库回退、登录状态异常或部分用户仍访问旧站。

本文给出一套可执行的"双阶段迁移"方案:先搭建新实例并完成全量同步,再持续追平文件与数据库增量;切换前短暂冻结写入,确认数据一致后修改流量入口,同时保留旧服务器作为可回滚节点。目标是把停机窗口压缩到可控范围,而不是不负责任地承诺绝对零停机。

一、适用场景

这套方法适合:

  • 更换云厂商、地域、账号或网络线路;
  • 从低配置实例升级到新的云服务器,但不能直接原地升配;
  • 从单机迁移到应用与数据库分离架构;
  • 网站、API、WordPress、Java/PHP/Node.js 服务需要缩短停机;
  • 需要迁移 Nginx、应用文件、用户上传目录和 MySQL 数据;
  • 续费前希望比较新老方案,并保留快速回滚能力。

如果业务包含支付、库存、消息队列、对象存储、定时任务或多主写入,迁移方案还要覆盖幂等、顺序、一致性和第三方回调,不能只照搬文件加数据库的流程。

二、迁移前先盘点,不要先买机器再猜配置

先记录旧服务器真实资源,而不是只记"4 核 8G":

bash 复制代码
lscpu
free -h
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINTS
df -hT
df -i
ip -br addr
ss -lntup

再记录高峰期 CPU、内存、磁盘与网络:

bash 复制代码
vmstat 1 60
iostat -xz 1 60
sar -n DEV 1 60

需要盘点的对象至少包括:

  • 操作系统、内核、时区、语言环境;
  • Nginx/Apache、运行时、依赖库和服务版本;
  • 网站代码、配置、证书、用户上传和持久化目录;
  • MySQL 版本、字符集、排序规则、存储引擎和数据量;
  • Redis、消息队列、定时任务、systemd 服务和容器卷;
  • 域名解析、固定 IP 白名单、第三方回调和防火墙规则;
  • 云盘容量、IOPS、吞吐、快照和备份策略。

配置判断

新实例不要机械复制旧规格。如果旧服务器 CPU 长期空闲但磁盘 await 很高,应优先核对云盘性能;如果应用经常 OOM,应检查内存峰值与容器限制;如果出口带宽持续触顶,应同时评估带宽和静态资源分发。迁移正是重新匹配计算、内存、磁盘、带宽和地域的机会。

三、目标架构:全量同步、增量追平、短暂冻结、可回滚

推荐把迁移拆成四个状态:

  1. 准备:新服务器只对运维人员开放,完成环境和安全配置;
  2. 全量:复制大部分静态文件与数据库基线,旧站继续服务;
  3. 增量:持续同步新增文件和数据库变更,缩小差距;
  4. 切换:短暂冻结旧站写入,做最后同步和校验,再切流量。

切换后不要立刻销毁旧服务器。先停止旧站写入和定时任务,将其保留为只读回滚点,观察一个完整业务高峰后再决定释放。

四、第一步:新服务器先搭好安全基线

创建新实例后,先完成:

  • 使用密钥或受控方式登录,禁止弱密码;
  • 安全组只开放当前需要的端口;
  • 数据库端口不直接暴露公网;
  • 安装系统更新、时间同步和监控;
  • 创建与旧环境一致的用户、目录和权限;
  • 部署 Nginx、应用运行时与数据库,但暂不承接公网流量。

检查时间与网络:

bash 复制代码
timedatectl
chronyc tracking 2>/dev/null || true
curl -4 ifconfig.me

如果两台服务器需要通过公网同步,应限制源 IP、使用 SSH 密钥并在迁移后撤销临时规则。更稳妥的做法是使用受控专线、VPN、对等连接或云厂商提供的迁移通道,但要核对跨地域和跨厂商可用性。

五、第二步:用 rsync 做文件全量与增量同步

1. 先做演练

在新服务器执行 dry-run:

bash 复制代码
rsync -aHAXvn --numeric-ids --delete-delay \
  -e 'ssh -p 22' root@OLD_IP:/srv/app/ /srv/app/

参数含义:

  • -a 保留常用属性并递归同步;
  • -HAX 尝试保留硬链接、ACL 和扩展属性;
  • --numeric-ids 按数字 UID/GID 处理所有者;
  • -n 只演练,不实际修改;
  • --delete-delay 延后删除目标端多余文件。

--delete-delay 有破坏性,只有确认目标目录是本次迁移副本且方向无误时才使用。首次执行建议先去掉删除参数并保存日志。

2. 正式全量同步

bash 复制代码
rsync -aHAXv --numeric-ids --partial --info=progress2 \
  --exclude='cache/' --exclude='tmp/' \
  -e 'ssh -p 22' root@OLD_IP:/srv/app/ /srv/app/

迁移 /etc 时不要整目录覆盖新系统。应只同步明确需要的站点配置、证书和服务单元,并逐项审查 IP、路径、用户与版本差异。

3. 增量同步

全量完成后定时再次运行相同的 rsync,每次只传变化部分。用户上传目录应重点追踪;缓存、临时文件和可重新构建的依赖可以排除,减少切换窗口。

同步后检查:

bash 复制代码
du -sh /srv/app
find /srv/app -type f | wc -l
rsync -aHAXvn --numeric-ids -e 'ssh -p 22' \
  root@OLD_IP:/srv/app/ /srv/app/

最后一次 dry-run 应只剩可解释的运行时变化。

六、第三步:MySQL 用可验证的方式追平增量

数据库迁移不能把正在运行的 MySQL 数据目录直接 rsync 到另一台机器。InnoDB 文件、redo log 和运行时状态需要一致性工具处理。

方案 A:停写窗口可接受

业务量较小时,可以先用一致性逻辑备份建立基线,切换时短暂停写并导出最后增量或重新导入:

bash 复制代码
mysqldump --single-transaction --routines --triggers --events \
  --hex-blob --set-gtid-purged=OFF --all-databases \
  | gzip > /backup/mysql-full.sql.gz

--single-transaction 主要保证 InnoDB 一致性;如果存在 MyISAM 等非事务表,需要单独设计锁与一致性方案。导出前检查磁盘空间,导入后检查用户、权限、事件和字符集。

方案 B:用复制或 binlog 缩短停写

数据量大、停机窗口短时,可让新 MySQL 先恢复全量基线,再从对应的 binlog 位点或 GTID 持续追赶。基本链路是:

text 复制代码
旧 MySQL 持续写入 -> binlog -> 新 MySQL 复制追平 -> 切换前停止写入 -> 等待延迟归零

实施前必须确认:

  • 源端已正确启用 binlog;
  • 新旧 MySQL 版本与复制方向受支持;
  • server_id、GTID、字符集和时区配置一致;
  • 复制账户仅授予必要权限并限制来源;
  • 没有在新库提前写入造成数据分叉;
  • 可以监控复制错误和延迟。

MySQL 8 可使用:

sql 复制代码
SHOW MASTER STATUS;
SHOW REPLICA STATUS\G

不同版本命令可能仍使用 SHOW SLAVE STATUS。不要只看 Seconds_Behind_Source;还要检查 IO/SQL 线程状态、Last_IO_Error、Last_SQL_Error,并在最终停写后确认位点或 GTID 已追平。

七、第四步:提前降低 DNS TTL,但别把 DNS 当成秒级开关

在计划切换前一个原 TTL 周期,将需要修改的记录 TTL 调低,例如从较长时间降低到几分钟级。具体值应根据 DNS 服务能力、查询量和业务风险决定,不虚构"所有用户几分钟内必然生效"。

检查解析:

bash 复制代码
dig example.com A
dig @1.1.1.1 example.com A
dig @8.8.8.8 example.com A

即使权威 DNS 已更新,递归缓存、操作系统、浏览器和本地网络仍可能保留旧地址。因此旧服务器必须继续响应一段时间,不能改完解析就立即关机。

如果入口使用负载均衡、EIP、反向代理或全局流量调度,可降低直接切换主机 IP 的复杂度,但仍需验证健康检查、会话、证书和源站白名单。

八、第五步:切换前短暂冻结写入

选择低峰窗口,按顺序执行:

  1. 暂停旧服务器上的定时任务、队列消费者和批处理;
  2. 将旧站切为维护或只读模式,阻止新写入;
  3. 执行最后一次文件增量同步;
  4. 等待数据库复制追平并确认无错误;
  5. 在新服务器本地验证应用、数据库和静态文件;
  6. 修改 DNS、负载均衡或流量入口;
  7. 继续保持旧服务器只读,观察真实请求。

常见暂停方式需按实际服务调整:

bash 复制代码
sudo systemctl stop app-worker.service
sudo systemctl list-timers --all
sudo crontab -l

不要粗暴停止整台机器,否则失去最后校验和快速回滚能力。

九、切换前验证:绕过 DNS 直接访问新服务器

使用 curl --resolve 将域名临时指向新 IP,不修改本机 hosts:

bash 复制代码
curl -vk --resolve example.com:443:NEW_IP https://example.com/

检查:

  • TLS 证书和 SNI 是否正确;
  • 首页、登录、上传、下单、回调等关键路径;
  • 静态资源与跨域配置;
  • 新服务器访问数据库、缓存和对象存储;
  • Nginx、应用、数据库日志是否有错误;
  • 防火墙、安全组、IP 白名单与第三方回调;
  • 新实例 CPU、内存、云盘和公网带宽是否满足预期。

还可以比较关键目录校验值。对大量文件,不要在高峰期无差别计算全盘哈希;优先检查配置、发布包和关键上传目录:

bash 复制代码
find /srv/app/releases/current -type f -print0 \
  | sort -z | xargs -0 sha256sum > /tmp/app.sha256

十、回滚条件要在切换前写清楚

建议预先定义触发回滚的指标,例如:

  • 关键接口错误率超过业务阈值;
  • 登录、支付、下单或上传不可用;
  • 数据库复制或数据校验异常;
  • 新服务器资源持续饱和;
  • 延迟明显高于旧环境且无法快速修复。

回滚并不只是把 DNS 改回去。如果新环境已经接受写入,直接切回旧库会丢失新数据。更安全的选择是:在确认稳定前,让单一环境保持写入权;如果新环境已经写入,则必须设计反向同步或业务补偿,不能盲目回切。

十一、迁移后的验证方法

至少观察一个完整业务高峰,并核对:

  • DNS 在主要地区解析到预期入口;
  • 新服务器请求量逐步上升,旧服务器请求量逐步下降;
  • 关键接口 P50/P95/P99、错误率和吞吐;
  • CPU、内存、Swap、云盘延迟、IOPS 和带宽;
  • MySQL 连接数、慢查询、锁等待和磁盘增长;
  • 用户上传、定时任务、消息队列和第三方回调;
  • 证书自动续期、监控、告警、备份和恢复演练。

查看仍访问旧服务器的请求:

bash 复制代码
sudo tail -f /var/log/nginx/access.log

确认旧流量降低到可接受范围后,再停止旧应用,但保留快照或备份到约定期限。删除旧资源前要再次确认数据、账单、快照和回滚期限。

十二、常见误区

误区 1:rsync 一次就完成迁移

错误。全量同步期间旧站仍会产生增量,必须再次追平并设置最终停写点。

误区 2:直接复制正在运行的 MySQL 数据目录

风险很高。应使用一致性备份、物理备份工具或受支持的复制方案。

误区 3:DNS TTL 调低后所有用户都会立刻切换

错误。多级缓存和客户端行为无法完全控制,旧入口应继续服务。

误区 4:新服务器配置越高,迁移就越安全

迁移风险主要来自数据一致性、入口切换、依赖和回滚。高配置不能替代流程。

误区 5:切换成功就立即删除旧服务器

应先覆盖完整高峰,验证监控、备份、回调和残余流量,再按计划释放。

十三、购买新云服务器时该怎么选

迁移前用旧环境的高峰数据决定新配置:

  1. CPU:看运行队列、P95 使用率和应用是否可并行;
  2. 内存:看可用内存、Swap、数据库缓存和容器峰值;
  3. 云盘 :看数据量、增长率、await、IOPS、吞吐和快照需求;
  4. 带宽:看公网峰值、文件大小、并发和是否配合 CDN;
  5. 地域:靠近主要用户和依赖,并满足合规与容灾要求;
  6. 高可用:根据允许的 RPO、RTO 选择备份、主从、多可用区或灾备。

如果只是规格不足,可以选择更合适的实例与云盘;如果单机同时承载应用、数据库、缓存和备份导致互相争抢,迁移时应考虑拆分;如果业务不能接受长时间停机,则应提前准备复制、负载均衡和回滚,而不是在切换当天临时补救。

云服务器迁移本质上是一项风险控制工程。先用数据确定新配置,再用全量加增量缩短停机,用明确的停写点保证一致性,用旧节点和备份保留回滚能力,才能让一次购买或迁移真正换来性能、稳定性和后续扩展空间。

相关推荐
宝塔面板1 小时前
宝塔拨测正式发布:网站测速、持续监控、异常告警
运维
Doris__HE1 小时前
【元脑服务器NF8260G7-NF8260M7技术规格分享】
运维·服务器·网络·数据库·性能优化
wdfk_prog1 小时前
ROS教程06:ROS1 Node 启动与停止流程
运维·缓存·docker·容器·ros
济南凡维1 小时前
Zebra Designer3试用文档
服务器·网络·zebra·打印机·斑马打印机
吴声子夜歌2 小时前
Shell编程实例——脚本编程的附加特性
linux·运维·shell
Wang's Blog2 小时前
Java 服务器: Linux-MySQL的rpm安装与初始化配置
java·服务器
叶总没有会2 小时前
Docker 基础+实战
运维·docker·云原生·容器
小白学大数据2 小时前
Python 项目实战:用 Flask 构建生产级 MySQL 增删改查 REST API
开发语言·人工智能·python·mysql·flask
蓝速科技2 小时前
会议室门牌显示模板选型与品牌视觉适配落地指南丨蓝速科技
大数据·运维·数据库·人工智能·科技