← 返回文章

一次可回滚的服务迁移,是怎样设计的

迁移不是复制文件,而是管理状态、流量与回滚边界。

本站目前处于试运行。这是一篇用于验证博客排版与发布流程的示例文章,可以直接替换为正式内容。

服务迁移在工程上常被低估:我们容易高估“复制”的简单性,却低估状态一致性、流量切换与回滚边界的复杂度。一次可靠的迁移,核心不是“完美无缺”,而是“任一步都能在安全停下并恢复”。

先定义迁移边界

迁移清单首先要回答的不是“有哪些文件”,而是“哪些状态属于这次变更”。

  1. 资产清单:明确服务、依赖、持久数据、配置和入口。
  2. 状态分类:区分强一致状态(例如数据库)与弱一致状态(例如缓存和统计)。
  3. 流量边界:定义域名、路由规则、会话以及证书的切换方式。
  4. 回滚边界:明确最小回滚单元、数据丢失窗口与重新同步方法。

把迁移范围写清楚,也要把明确不迁移的部分写清楚。排除项不是遗漏,而是架构决策;它决定了新旧环境之间不会无意形成第二条生产路径。

让切换可验证

真正的切换应该从“把全部流量指过去”,变成“一组逐层收敛的证据”。

先验证不依赖 DNS 的链路

新环境可以先通过固定解析目标进行验证。这样在用户流量尚未改变之前,就能检查证书、路由、登录与数据访问:

bash
curl --resolve example.com:443:203.0.113.10 \
  -I https://example.com/

这一步把“DNS 是否生效”和“新服务是否正确”拆成两个独立问题。出现异常时,我们能直接知道应该检查哪一层。

再验证真实公网入口

DNS 切换后,不要只看控制台。至少同时检查:

  • 权威 DNS 与两个公共递归解析器返回的地址。
  • HTTPS 证书的域名、签发方与有效期。
  • 关键页面的状态码、跳转位置和实际远端 IP。
  • 新旧主机的服务状态,确保不会在重启后产生双写。

回滚不是一句口号

回滚必须经过设计和验证。一个实用的原则是:

把不可回滚的操作放在迁移边界之外;把不可逆的变更延后到证据充分之后执行。

对于单机静态服务或 SQLite 应用,可以保留旧机的数据目录,停止并禁用旧服务,但暂不删除。这样既避免旧机重启后形成分叉,也保留了清晰的恢复入口。

在确认观察窗口稳定之后,再处理旧环境清理。清理顺序同样重要:先移除仅用于传输的临时归档,再根据明确的保留策略处理旧数据,不能把“磁盘整理”误当成迁移完成条件。


一次好的迁移,不是追求零风险,而是让风险可见、可控、可逆;把边界画清楚,把证据做充分,把回滚当成真正的工程能力。