如何在不停机的情况下迁移 VPS

零停机迁移 VPS:双机并行、持续增量复制、缩短记录 TTL、脚本化交接与可回滚路径。Core 套餐每月 $6,年付 $4.80/月。
零停机迁移 VPS 的关键在于:新旧双机并行、持续增量复制、缩短记录 TTL、脚本化交接和可回滚路径。Core 套餐标价每月 $6,年付合 $4.80/月。
停机发生在写入切换的那一刻,而不是文件复制的过程中
每一次迁移都由两把计时器主宰:一是字节完成传输所需的时间,二是服务出现抖动的时间。前者以小时计,不会让任何人难堪;后者以秒计,却在每一个亲历者的记忆里定义了整个项目。让两台主机同时保持在线,从旧机持续向新机推送增量数据,把抖动压缩到你重定向新写入的那一瞬间——一次提升、一条记录的修改、一次配置开关。任何数据卷都无需卸载、镜像或实体搬运。
交接可以落在三个环节上,而一次有纪律的迁移只选择其中一个。解析路线:在缩短缓存生存期之后修改地址记录(A 或 AAAA);存储路线:提升从库,让应用程序自行发现新上位的主库;软件路线:在应用程序内部翻转端点。哪条路线合适,取决于客户端如何找到你——RFC 1034 描述了第一条路线所身处的名称与缓存世界,它的教训很直白:你昨天发布的答案会一直对外服务,直到它的租约到期,而租约时长正是你亲自批准的。
持续流式复制是让上述任何一种切换都变得低成本的基础机制。新机持续吞入稳定的增量流——通过反复的 rsync 遍历同步文件树,通过数据库引擎自己的变更日志(PostgreSQL 的 WAL、MySQL 的 binlog)重放事务,通过技术栈中已有的队列传递事件。落后于主库的距离就是生命体征:以秒计的延迟意味着一台温备机;以分钟计意味着上游某个环节卡住了;以小时计则意味着整个排期在无人看表的情况下悄悄崩塌。
把迁移拖成整个周末的典型错误,是先撤掉还在干活的那台机器。为了复制磁盘而冻结一切听起来很负责,但它会把每一个潜在的缺陷——版本偏差、缺失的依赖库、过期的凭据——都变成一场有观众围观的线上事故。复制和验证属于排练阶段,此时老兵仍在服务;只有切换本身以及紧随其后的探测,才配得上一个正式命名的维护窗口。
带着一个心智模型读完后面所有内容:两台在线的机器、单向的增量流、唯一的一次重定向——接下来的每一节都会在真实流量和真实的焦躁之下拆解其中一块。
VPS $4.80* 起(年付期限),存储 1–5 TB NVMe 年付折合 $24/月起,带 IPMI 的独立服务器 $39.20/月起。加密货币账单,免 KYC。
立即启动在任何有价值的数据到达之前,先把新机武装好
一台空服务器是装着定时器的陷阱。趁它还一无所有的时候彻底加固——访问控制、包过滤、补丁自动化、时间同步——因为数据一到,你的自由时间就到头了。把基线复刻当成习惯而不是存档:几年之后你会在另一台机器上重建这套一模一样的环境,所以让每一个决策都清晰、成文,并保存在集群之外的地方。本页的一切都假设你拥有两端的 root 权限——一个把 shell 藏起来的托管面板,同样会把这套手册所要应对的故障模式一并藏起来。
软件包的对等性排在第一位:守护进程的代际要一致,而不只是名字一致——一个不匹配的次要版本会复现出源端从未表现过、也解释不了的行为。匹配数字属主(uid 1000 是惯例,不是法律),让传输过去的文件在落地时保持完整一致的权限。把包过滤规则写成文件并用 nft -f /etc/nftables.conf 加载;把机器纳入 unattended-upgrades;然后用 chronyc tracking 审问一下时钟,因为所有复制协议都用时间戳来衡量距离,一台漂移的时钟会从健康的同步流里凭空造出幽灵延迟。
在负载到达之前,访问控制值得一场私密的仪式:生成一对专用密钥(ssh-keygen -t ed25519),把公钥装进新机的 authorized_keys,并按照sshd 手册的要求废除基于密码提示的登录(PasswordAuthentication no)。趁磁盘还空着做这些事,任何错误都无关痛痒;留到交接时才做,每一个错误都会代价高昂、当众出丑,并永远写进某个人的事故频道。
证据高于意图:启动这台空机器,部署合成内容,把整条链路演练一遍——解释器、数据存储、缓存、调度器。缺失的扩展和缺失的内核模块会在这里暴露,此时重装只花十分钟、换来一耸肩,而不是在有人围观时才在探测环节爆雷。这唯一一次空跑能消灭绝大多数迁移意外,趁它们还没花掉你一分钱。
当这台空载主机干净利落地跑完合成负载并通过安全态势检查,它就从一台空白服务器毕业成了认证过的目的地。
持续推送增量,直到从库只落后几次心跳
一次性批量复制会让时间冻结,复制则拒绝冻结。这个区别决定了目的地最终是否一致:对一套在线的数据存储做单次拷贝,会把它切成一层层互不兼容的地层;而引擎自己的变更日志会按提交顺序重放事务,最终得到一个逐字节一致的孪生体。目录树可以欣然容忍朴素的拷贝;关系型引擎则断然拒绝——把一份原始文件副本递给在线运行的引擎,它会在第一次写入时报复回来,毫不讲价。
文件系统走的是省事的路线:每 5 分钟执行一轮 rsync -aAX --delete --info=progress2 /srv/ root@new:/srv/ 的定时循环即可把漂移压得很浅,rsync 参考手册逐项列出了哪些归档开关能保留属主、扩展属性和稀疏文件。PostgreSQL 则走得更远:pg_basebackup -R 播下一个物理孪生体,primary_conninfo 维持数据流,主库上的 pg_stat_replication 会披露每个订阅者的 replay_lag,热备章节对此有详尽的记载。
MySQL 的方言不同,语法逻辑却相通。从一致性快照引导,用 CHANGE REPLICATION SOURCE TO 登记主库的坐标,然后盯着 Seconds_Behind_Source,直到它稳定进入个位数,详见官方复制指南。凡是存在应用层通道的地方——只追加日志、队列主题、导出钩子——优先用它;软件自己最清楚哪些字节变了,而且这份知识能挺过那些会彻底粉碎文件系统假设的重构。
这里的事故各有各的签名。对在线表空间文件做原始复制,会得到一个看似合理、却在第一次插入时就损坏的数据卷——数量级对得上,校验和对不上。一个目标路径写反了的 --delete 会以极其礼貌的方式抹掉目的地自己的文件。而一份上周二就悄悄失效的定时任务,只会在延迟跨过小时级时才现身;要告警的是实测距离,而不是某条定时器条目还活着这件事本身。
当从库在寻常一天里最差的时刻距离主库仍在数秒之内,目的地就不再是一份副本,而是一台温备机——这是后面每一步都在默默假设的前提。
提前一天缩短解析器的记忆
发布一个新地址是瞬时的;受众落到新地址上却不是。你的访客与区域文件之间的每一台递归解析器都会保留旧答案,直到租约到期,所以中午改动的记录会持续把一部分读者派往一台你早已降级的机器。这支残余部队的规模和持续时间,早在区域文件最后一次被修改的那一刻——也就是几周前、由你亲手、悄无声息地——就已注定。注册局公布生存期;缓存执行生存期。
一条规则让时序变得可确定:已缓存的生存期无法被追溯缩短。一个当前写着 86400 的字段,即使你调低了它,也会继续按旧值自作主张最长一天,所以下调必须提前 24 小时进行,而不是和切换同场。分阶段执行:前一天降到 300,切换当天早晨降到 60,并用 dig +norecurse 审问线上答案,这样你观察到的是外部缓存真正持有的东西,而不是你对它们的想当然。
两份 RFC 划定了边界。RFC 2181 梳理了肯定答案的生存期语义;RFC 2308 覆盖了否定答案——解析器同样会记住失败,切换期间一次孤立的失败查询,会教唆成千上万的缓存在过期响应期内持续失败。整个窗口期内把否定答案的 TTL 保持得很短,等退役完成后再放宽。
两种失败形态最常见。在切换瞬间才改 TTL,会把一部分访客搁浅在已降级的主机上好几个小时——教科书版本,每一篇复盘都会背诵。更隐蔽的变体是:邮件交换器、集成伙伴和监控服务商运行着私有策略下的解析器,所以收敛到来得像一条曲线,而不是一个瞬间。从多个网络、至少一家移动运营商去验证;你自己的工作站证明不了任何事,它的缓存早被你亲手清空了。
一天的短生存期答案不会让任何访客有所察觉,却能把地址修改从整个迁移中风险最高的动作,变成清单上最无聊的一行。
切换本身:五个动作,十分钟,零戏剧性
排练过的交接是行政流程;没排练过的交接是剧场表演。五个动作,大约 10 分钟:暂停旧机上的新写入,排干最后的增量,重定向写入,探测关键路径,然后观察全局收敛。迁移圈子里每一场灾难故事,都始于这五个动作中的某一个被临场即兴,而不是在一次性孪生机上排练过两遍。这里没有任何东西是天才式的;整门纪律的全部内容就是拒绝即兴。
暂停写入是基石。静默旧机的数据存储——MySQL 中设 read_only=ON,或者撤销写权限,或者启用应用自带的维护模式——让收尾的增量落在静止的源上,从而让目的地以一致收尾,而不是差不多一致。省掉冻结这一步,你就亲手制造了脑裂:两台主库各自愉快地接受互不相同的历史,这处伤口之后要靠导出的电子表格、羞愧的道歉和一星期没人预算过的对账来弥合。
沿你开局选定的路线重定向:修改记录,或者提升从库——SELECT pg_is_in_recovery(); 返回 f 即证明新机已经上位——或者改指应用的端点。然后像对手一样探测:curl -fk https://example.com/health 探前门,当然要探,但同样要提交登录表单,把一件商品走完购买流程,手动触发一次夜间批处理。复制所锤炼的正是写入路径;一张首页证明不了其中任何一条,也安抚不了任何一个真正要紧的人。
反复出现的翻车:旧机上的调度器 worker 在冻结之后继续存活并写入数小时;告警在整个窗口期内反复震荡,直到所有人都屏蔽了频道——包括真实故障发生的时刻;探测覆盖了落地页,而 POST 端点在暗处冒烟。至于目的地本身,按 $6/月 的标价(年付合 $4.80/月)入手 Core,并让两台机器的账单贯穿整个窗口——从容的节奏每天只花几毛钱,却能保住你的夜晚。
在一台牺牲机上把这套流程排练两遍,正式切换就会塌缩成肌肉记忆:十分钟的从容不迫,唯一的紧张是看着延迟仪表归零。
旧机就是你的保险;退订要晚
退役和迁移属于同一个项目,日历以流量周期为单位。让老兵至少满负荷运行 7 个整天——足够覆盖每周任务、每月汇总,以及那位解析器虔诚供奉远古答案的客户。如果服务带月度周期,就是几周;以天为单位只是底线,不是目标。每发现一个这样的遗漏,只要旧机还在应答都轻而易举;退订之后,它就退化成一张提给已被清空数据卷的支持工单,和一声追悔莫及。
整个退休期都要观察老兵,而不只是新人。被遗弃的定时任务会以外发邮件无处可去的形式自我暴露——mailq 一眼打印出队列;crontab -l 列出每晚仍在骚动的东西。续期任务可能还在刷新老兵 web 根目录上的证书,悄悄把访客分摊到两个源头之间;certbot renew 的时间戳会揭示陌生访客真正还在光顾哪一台。伙伴防火墙和上游负载均衡器会持续指回源机数周,除非有人去通知他们,而那个人就是你。
在拔掉插头之前,先存好逃生通道:一份完整的快照,存放在两台机器之外,用 sha256sum 做好校验,让归档之后能自证完整性;再加上那些容易成为孤儿的细枝末节——任务清单、包过滤规则、续期配置(参见Let's Encrypt 文档)。快照可以随结算时的附加选项购买;它买到的那份安心是:恢复,永远好过深夜凭记忆重建。
清除冲动是臭名昭著的失败:交接周二告捷,退订周四落地,周五迎来了那个只在这里跑过的月度对账任务。它的孪生错误是转发回环——一条遗留的负载均衡规则仍在把请求重定向到新机,而新机又把一条遗留路径代理回旧机,两台机器彬彬有礼地把访客来回弹接,直到有人逐行读完访问日志。决定回环真正何时停止的,是日志,不是回忆。
以审计员注销凭据的方式退役基础设施:在预先公布的日子,依据一份成文的计划,并让昨天的归档躺在冷存储里、校验已通过。
地址不会跟着搬家;要围绕你留下的那一个做规划
IPv4 空间属于网络,不属于客户:你的服务所应答的那个地址,是从旧服务商的地址块里借来的,离开时会留在原地。因此每一次迁移都内嵌了一场地址迁移,而拒绝承认这一点的团队,会在最终探测而非规划阶段撞上硬编码的字面量——藏在 cron 脚本里、伙伴白名单里、监控探针里——那是此类发现所能发生的最昂贵的场所。
大多数受众不需要任何奇技淫巧:前一节里缩短生存期的记录修改搬走的是名字,新机的地址不过是与之不同而已。对于极少数硬性依赖固定端点的客户——按来源过滤的伙伴、无视域名的老旧设备——不如搭建一个前廊:一个由你掌控的代理或隧道入口,架设在两台机器之前,把动不了的运营商地址变成你拥有的可携带地址。多孔的依赖会在此刻、在两扇门都还开着的便宜时机浮出水面。
有意识地重建身份类管道:如果邮件牵涉其中,从面板设置反向记录,更新指明新地址的发件方框架,探针目标和伙伴过滤通过工单而非道歉来修订。你自己的终端会第一个抗议——用 ssh-keygen -R old.example.com 清除过期指纹(手册)——并抵制 -o StrictHostKeyChecking=no 这种全民恶习,它用一行 known-hosts 的编辑,换来了永久的、未经审视的轻信。
团队容易栽跟头的地方:字面量大搜捕穿过了应用代码,却绕过了外围——邻近服务器上的定时任务、集成任务的执行器、某台笔记本上的归档脚本。把 /etc、每一份可读的 crontab 和陈年工单都梳一遍;大多数运维靠这个方法找回两三个被遗忘的字面量。203.0.113.10 这类文档示例地址,只有在替换成真实即将迁走的地址之后,才能当作搜索模式使用。
把地址变更当作一项有着自己验收标准的独立交付物来对待,那么人人惧怕的这一段,就会变成无人记得的这一段。
先在一台用完即弃的孪生机上全流程彩排
未经排练的迁移是一份由你的用户来打分的草稿。彩排之所以便宜,恰恰因为练习对象是用完即弃的:拉起一台牺牲孪生机,执行完整序列——武装、流式复制、生存期修改、冻结、重定向、探测——并为每个环节计时,而不是凭直觉猜。你带进正式切换现场的数字,应当是带着误差棒的测量值,而不是带着小数点的乐观。
给一切盖上时间戳:把 date -u +%s 写进 runbook,runbook 本身放入 git 做版本管理,这样每次彩排都会留下带日期的 diff——哪个环节跑久了、哪里报了错、延迟曲线实际上如何弯折。只存在于某一位管理员记忆中的计划,只能被排练检验一次——就在压力最大的那一刻——这与从未排练过毫无区别。
彩排的产出就是正式的排期:如果收尾增量需要 12 分钟、全球收敛需要 45 分钟,维护窗口就是一个站得住脚的数字,而不是一个愿望。提前用 rsync --dry-run(参考手册)给文件树阶段估个价,撤退路线也要同样彩排——恢复归档、改回记录、确认老兵仍在服务——因为一条未经测试的回滚路径是一篇睡前故事,不是任何人在压力下能执行的操作规程。
有两个陷阱专门埋伏在彩排环节。什么都练了、唯独不练写入冻结,因为暂停一个想象中的负载看起来像演戏——结果最关键的那把锁直到现实送上观众时才第一次被测试。以及因为合成数据明显无恙而跳过目的地探测,这会把整个团队训练成把探测当成走过场。两者的成因都是惯性而非恶意;最枯燥的步骤要练得最狠,因为它们才是那些会大声嚷着失败的家伙。
如果目的地从第一脚开机就配得上裸金属服务器——整核算力、板载控制台——按 $49/月 的标价(年付合 $39.20/月)下单 Forge,并用同样的方式对着它操练;整套编排原样存活,只是底下的舞台换了。
迁移全流程:按此顺序执行
从头到尾复述一遍:趁旧机还在创造价值时武装并加固新机;打开增量数据流并盯住延迟;提前一天缩短解析器生存期;执行五步交接;让老兵再站岗一周;归档;退役。这个顺序是承重结构——每一阶段都在为下一阶段制造前提,跳步会把几分钟的工作变成几个通宵的抢救。本页由一个亲眼目睹过未排练切换拖成整个周末的人写就;那个人如今警觉得很,而你可以把这份谨慎整个借走。
具体顺序:打基线——用 ssh-keygen -t ed25519 建立专用密钥对、包过滤规则落成文件、补丁自动化、时钟同步。然后是移动:rsync -aAX 循环对付文件树,PostgreSQL 用 pg_basebackup 加持续流式复制,MySQL 登记主库坐标,告警绑定在实测延迟上,让安静意味着健康而不是死亡。从库获得备机资格的标志,是它最差的日常延迟以秒计,而不是首次复制完成的那一刻。
切换前夜:生存期降到 300,并通知每一位运行私有解析器的伙伴。切换当天早晨:冻结写入,排干残余,重定向——改记录、提升从库或改端点——然后像入侵者一样探测每一条变更路径,并从你自己不掌控的网络观察收敛。冻结神圣不可侵犯;双主分叉是这套方法唯一无法低成本愈合的伤口,清单上的其他一切,都是为了让冻结的时刻尽量短暂而存在的。
切换后一周:老兵保持开机,它的队列和定时任务有人盯守,续期原封不动,让迟到的访客慢慢流入、被遗忘的任务自己招供。关机之前:快照加上零散产物——过滤规则集、续期配置、任务清单——封进同一个归档。VPS 与裸金属的对比会告诉你新机的下一任继任者应该落脚何处;它们之间的编排保持不变。
整套流程做两遍——一遍对着牺牲孪生机,一遍正式留档——第二遍就会自动跑完:十分钟的从容不迫,手感与排练时分毫不差。这正是本页的全部野心。
VPSbit 能替我迁移服务器吗?
我们不提供托管迁移服务——root 始终在你手里,这套手册也是。在独立服务器档位上,远程运维($24/月 附加服务)可以协助物理层面的操作,例如连接控制台;而数据搬迁完全由你亲自执行。
如何在不更换 IP 的前提下完成迁移?
做不到;地址属于服务商的网络。绕开的办法是缩短记录生存期并快速修改记录,或者在两台机器前面架一个代理加隧道入口——如果客户端确实要求端点保持不变的话。
哪个迁移方向最常见?
主流云服务商迁往免 KYC 站点的入站流量最多,动因通常是账单或司法辖区偏好,<a href='../../offshore-vps/'>离岸 VPS 指南</a>对此有详细说明。流式复制的机制双向完全一致,差异只在入驻环节——在这里,是一个邮箱或令牌,外加一张加密货币账单。
旧服务器应该在线多久?
不少于一个完整的流量周期,通常是一周,让迟缓的客户端、有耐心的解析器和被遗漏的定时任务全部现形,此时撤退的代价只是一次记录修改。退役之前先存好快照;后悔比归档贵得多。
目的地的磁盘需要比源机大吗?
假设从库会携带一份接近完整的副本,所以容量至少持平或超过旧机。当源机已经塞满自己的存储时,320 GB NVMe 档位上的第二台机器可以顺理成章地兼任复制目标。