促销季买到便宜的新机器只是第一步,真正让人头疼的是接下来这几天:老服务器上跑着网站、数据库、几个自建服务,还有一堆定时任务,怎么把它原样搬到新机器上,同时把停机时间压到最短。多数人第一次做迁移都会低估工作量,以为 rsync 一把梭就完事,结果卡在数据库不一致、证书失效、定时任务忘搬这些细节上,断断续续折腾一周。迁移真正的难点不在传文件,而在切换窗口的编排:什么先动、什么后动、出问题怎么退回去。 这篇按实操顺序走一遍:先用三笔账决定要不要迁、怎么迁;再把老机器盘点清楚,避免漏掉藏在角落里的服务;然后是数据搬迁的具体工具和数据一致性的处理方式;最后是切换窗口里的每一步动作和验收清单。命令都是可以在 Debian 或者 Ubuntu 上直接跑的,涉及商家政策的部分标注了来源,价格与政策以官网实时页面为准。
迁移前先算三笔账
第一笔是停机窗口。你的服务能忍受多久不可用,决定了采用哪种迁移方式:如果有 4 小时以上的窗口,可以直接停服再搬迁,最简单也最安全;如果只能接受几分钟,那就必须做增量同步加快速切换,复杂度高一个量级。第二笔是数据量。几十 GB 的数据在普通带宽下几小时能传完,几百 GB 就要考虑要不要先用压缩包传一次基线、再用增量补齐,或者干脆用云盘中转。第三笔是回滚成本:老机器是否还能开机、域名解析改回去要多长时间、数据回滚是否会导致期间新增的数据丢失。这三笔账算完,方案基本就定了。 还有一件事要提前确认:新机器什么时候能开通。不同商家的处理方式差别不小,以即时开通为卖点的商家(例如 RackNerd,条款里写明 KVM VPS 付款后即刻下发)付款后几分钟就能拿到机器,而少数商家在条款里写明订单按工作日处理,周末下单要等到下周一。这直接影响你安排切换窗口的时间点,别把迁移排在周日晚上。另外如果你买的是续费换商家那种方案,记得先把新机器的测试 IP 测一遍,确认线路符合预期再开始搬,避免搬完才发现换了个更难用的环境。
第一步:把老机器盘点清楚
这一步最枯燥,也最能决定迁移顺不顺利。很多人凭印象列服务,结果搬完发现某个半年前配的 webhook 没了、证书自动续期没配、数据库备份的 cron 还指着老机器。正确的做法是让系统自己报出清单,而不是靠回忆。下面这几条命令覆盖了绝大多数情况,把输出整理成一份文档存到本地,迁移过程中反复对照。
| 要盘点什么 | 命令 | 容易漏掉的点 |
|---|---|---|
| 监听端口与进程 | ss -tulpn |
只监听 127.0.0.1 的服务最容易被忽略 |
| 运行中的服务 | systemctl list-units --type=service --state=running |
手动用 nohup 起的进程不在里面,用 ps aux 交叉核对 |
| 定时任务 | crontab -l、/etc/cron.d/、systemctl list-timers |
systemd timer 和 cron 两套都得查 |
| 容器 | docker ps -a、docker volume ls |
数据卷不在镜像里,必须单独备份 |
| Web 配置 | nginx -T 或 apache2ctl -S |
包含 include 的碎片配置文件要整目录拷 |
| 证书 | ls /etc/letsencrypt/live/ |
换 IP 后部分验证方式需要重新签发 |
| DNS 与第三方 | 解析记录、webhook、API 白名单 | IP 白名单类服务改完 DNS 还得改配置 |
盘点完还要做一次”能不能重来”的检查,这是最容易省掉又最不该省的一步。挑几个关键服务,在本地或者临时容器里试着按文档重建一遍,看看是不是真的能在没有老机器的情况下跑起来。这个动作能提前暴露两件事:依赖没有记录在案的软件包,以及需要人工交互才能完成的初始化步骤。真到了切换窗口再去发现这些,停机时间会翻倍。
第二步:新机器上重建环境,不要照搬系统
新手常犯的错误是想着”把老机器的系统镜像直接导过来”,这条路由概率踩坑:驱动和内核版本对不上、旧的配置文件里写死了老 IP、商家之间的控制面板不兼容。除非你的环境极其复杂,否则重建比搬迁快得多,而且顺手能清理掉积累的垃圾。重建的顺序建议是先做基础层(系统更新、时区与语言、SSH 密钥登录、防火墙规则、fail2ban),再装运行时(Nginx 或 Caddy、PHP、Node、Docker),最后才装应用。基础层那部分可以直接照 VPS 安全加固的实战配置 做一遍,十分钟的事,但能省掉以后被爆破的麻烦。 如果老机器上的服务是用 Docker Compose 编排的,重建会轻松很多:把 compose 文件和 .env 拷过去,再把数据卷恢复回去就能起。这也是当初把服务容器化的最大回报:迁移时你搬的是配置和数据,跟运行环境无关。整套自建服务的编排写法可以参考 用一台 VPS 部署个人全栈云服务,里面那几个服务的迁移方式基本可以套用到任何地方。需要提醒的是数据卷默认不会跟着镜像走,必须单独打包,具体命令在下一节。
第三步:数据怎么搬
数据大体分三类,每一类的搬迁方式和注意点都不一样,混在一起处理就会出问题。文件类最省事,数据库类最危险,用 rsync 可以做增量、可以续传、可以保持权限和硬链接;数据库类最危险,直接拷数据文件在写入过程中会得到损坏的副本,必须用逻辑导出或者停服冷备;容器卷类最容易被忘记,因为它藏在 /var/lib/docker/volumes 下面,不在你平时打交道的目录里。
文件:rsync 做增量,最后一遍加 –delete
文件同步用 rsync 是标准做法,把权限、属主、ACL 和扩展属性都带上,可以避免搬过去之后 Web 服务读不了文件。第一次同步数据量大,建议挂 screen 或者 tmux 跑,避免 SSH 断线中断。业务不停的情况下先做一到两轮增量,把大部分数据提前推过去,切换窗口里只需要再跑一次增量加一个 --delete,几秒钟就能补齐差异。这条 --delete 是切换窗口才加的,平时不要带,否则老机器上误删的文件会同步到新机器,把备份也一起删掉。
数据库:导出必须带 –single-transaction
MySQL 或者 MariaDB 在业务运行时导出,要加 --single-transaction,它会在一个事务里读出一致性快照,不会锁表导致线上写不进去,同时避免导出到一半数据被改动造成的不一致。导出时把存储过程、触发器和事件也带上,这些经常被漏掉,恢复后才发现某些定时逻辑消失了。PostgreSQL 用 pg_dump 的自定义格式,恢复时更灵活。如果数据量很大、导出耗时长,更稳妥的方式是在切换窗口里先停写再冷备,虽然停机时间长一点,但一致性最有保障。
容器数据卷:单独打包,别指望镜像
Docker 的数据卷不在镜像里,删掉容器不会删卷,但换机器时也不会自动跟过去。做法是临时起一个容器把卷目录打包成 tar,拷到新机器之后解回对应的卷。如果卷比较多,可以把 compose 里用到的卷名先列出来,逐个打包,避免漏。恢复之后记得用 docker compose up -d 起服务,再确认数据目录的属主和容器内进程的 UID 一致,否则会出现”服务起来了但写不进数据”的怪问题。
大文件与异地备份:rclone 或 restic
如果你平时就用对象存储做备份,迁移时可以让新老机器都指向同一个存储桶,用 rclone 做一次全量同步最省事。restic 这类快照型备份工具则可以在迁移前后各打一次快照,把”迁移前的状态”和”迁移后的状态”都留下来,出问题时对比恢复点非常方便。这两种方式还有个附带好处:它们验证过数据能完整恢复,等于顺手做了一次备份演练。
第四步:切换窗口里的操作顺序
切换是整个迁移里唯一不能出错的部分,顺序比技巧重要。第一步是提前把域名的 TTL 降下来,改到 300 秒左右,并且至少在切换前 24 到 48 小时完成,否则解析缓存会让一部分访客在半小时内还指向老机器。第二步是通知用户或者挂维护页,除非你的服务本身允许短暂不可用。第三步是停写:把应用切到维护模式、停止定时任务、停掉数据库写入,确保切换期间不会产生新数据。 第四步是最后一遍增量同步加数据导出,把停写之后剩下的差异推过去,同时导出数据库并导入新机器。第五步改 DNS 解析指向新 IP,然后立刻用多个解析服务器验证,dig @8.8.8.8 和本机默认解析各查一次,确认新记录已经生效。第六步是逐项验收:站点能不能打开、HTTPS 证书是否正常、登录和写入是否正常、后台任务是否恢复、邮件能不能发出去。全部通过之后才解除维护模式,并且把老机器继续保留运行至少一周,作为随时可以切回去的回滚点。
这里有一类细节值得单独说:证书。如果你的证书是 Let’s Encrypt 通过 HTTP 文件验证签发的,换 IP 之后续期会失败,因为验证请求打到的是新机器的 Web 根目录。如果新机器配置一致就不会有问题,但如果你顺手换了 Web 服务器或者改了站点根目录,续期就会断掉。迁完之后手动跑一次续期测试,比等到两个月后证书过期才发现要好得多。另外 PTR 记录(反向解析)通常要在新商家的控制面板里手动设置,搬完记得补上,它对邮件送达率有实际影响。
第五步:并行验收期检查什么
切换完成不等于迁移结束,接下来的三到七天是发现问题的高峰期。最需要盯的是日志,新机器的访问日志里如果出现大量 500 或者 404 集中在某个路径,多半是某个配置文件没搬全或者路径写错了。然后是定时任务,很多任务是一天或者一周跑一次,只有等到执行时间才会暴露问题,所以验收期至少要覆盖一个完整的任务周期。第三是外部依赖,webhook 回调、第三方 API 的白名单、邮件发送配额,这些改完 IP 之后都可能失效,而它们往往在几天后你才发现某个通知没收到。 还有一个习惯值得养成:把老机器上的监控和告警也一起迁过来,或者至少在新机器上部署一套。迁移过程中最怕的是”没人告诉你出问题了”,等用户来反馈时,故障可能已经持续了好几个小时。
迁移之后别急着做的三件事
第一件是别急着退掉老机器。至少保留一个完整的账单周期,确认新机器稳定、业务数据没有丢失、所有定时任务都正常之后再取消。保留期间的成本相对于迁移失败重来的成本,基本可以忽略。第二件是别急着删除老机器上的数据,即使退了服务,也先在本地留一份完整备份,等到新机器运行满一个月再清理。第三件是别忘了更新文档:盘点时整理的那份清单要更新成新机器的信息,包括 IP、端口、证书位置、定时任务、备份路径,下次迁移时你会感谢现在的自己。
常见问题
迁移一定要停机吗?
看服务的写入门槛。纯静态站点和读多写少的服务可以做到几乎不停机,因为文件可以用 rsync 增量追平,切换时只差最后一次同步。带数据库写入的业务要做到零停机,需要主从复制或者双写这类架构,成本远高于收益;对多数中小站点来说,选一个访问低谷停机十到三十分钟是更划算的方案。
rsync 传了几十 GB 中断了怎么办?
直接重跑同一条命令即可,rsync 默认按文件比对,已经传完的部分会跳过,只补差异。这也是它比 scp 更适合大目录的原因。数据量特别大的话,建议放在 tmux 或者 screen 里执行,避免网络波动导致 SSH 断开。第一次同步时可以临时加压缩选项减少流量,但要留意 CPU 占用。
DNS 改完多久生效?
取决于你原来的 TTL 设置。如果 TTL 是 3600 秒,改完之后最长一小时内还会有访客访问老机器;如果提前把 TTL 降到 300 秒,切换时的影响窗口就能压到五分钟量级。实际操作中,切换后立刻用 dig @8.8.8.8 域名 等公共解析验证是必要的,但要注意各地运营商的缓存刷新速度不一致,别因为一个地区的解析还没更新就反复改记录。
新机器和老机器的系统版本不一样会有影响吗?
会有,但没有想象中严重。主要影响在软件包版本和配置语法上,比如 PHP 大版本之间的配置项差异、Nginx 某些指令在新版本的行为变化。稳妥的做法是新机器上先按当前稳定版本装一遍,把配置逐项检查之后再导数据;如果时间紧,至少把 Web 服务器和数据库的版本对齐,能避免大部分兼容问题。
能不能用控制面板的”迁移”功能一键搬?
分情况。同一家商家的机房迁移功能通常是真的省事,比如 搬瓦工 的 E-Commerce 线就支持在机房之间免费迁移且不丢数据;但跨商家的整机迁移基本没有通用方案,商家的快照和备份也是绑在自己平台上的,搬不到别家。所以跨商家迁移的正确姿势仍然是”盘点、重建、搬数据”这条流程,面板功能只能帮你处理同一家内部的机房切换。
切回去(回滚)麻烦吗?
如果只是改 DNS,回滚很快:把解析改回老 IP,等缓存过期即可,前提是老机器还没退、数据还在、服务还能启动。这也是为什么迁移完成后要把老机器继续挂一到四周。真正的麻烦是切换期间新机器上产生的新数据:如果用户已经在新机器上注册、下单或者上传了文件,回滚就会丢这些数据,所以验收要尽量在维护窗口内完成。
总结
把这次迁移拆开看,无非是四件事:盘点时不漏、重建时不偷懒、搬数据时保证一致、切换时留好退路。真正花时间的是把散落在系统各处的配置和服务找出来,传文件本身反而最简单,以及在窗口内按顺序执行。命令层面没有玄学,难的是提前准备:清单要提前整理、TTL 要提前降、老机器要提前保留、验收周期要覆盖完整的定时任务周期。 给你一个可以直接执行的最小方案:选一个访问低谷的时段,提前 48 小时把 TTL 降到 300 秒;按盘点表把服务和配置列出来,在新机器上重建基础环境和运行时;文件用 rsync 提前跑两轮增量,数据库用带一致性选项的导出;窗口内停写、补增量、导数据、改解析、逐项验收;老机器保留一个账单周期不退款。这套流程不需要任何特殊工具,全用系统自带命令就能完成。最后提醒一下,各家商家的开通时间、迁移政策和退款窗口差别不小,动手前请以官网实时条款为准;如果你还没买新机器,可以对照我们整理的 黑五 VPS 蹲机攻略 里那三张表,把可迁移能力和退款窗口当作筛选条件,出问题时才不至于被动。
原创文章,作者:kp51,如若转载,请注明出处:https://www.kepu51.com/linux-ops/1131.html
