最近遇到一个老服务迁移的案例。

几项运行多年的服务,需要从 AWS 迁移到一台新的 VPS。原服务器使用 Ubuntu 16.04,新服务器使用 Ubuntu 22.04。

负责迁移的人有多年的运维经验。他借助 AI,先把原服务器上的程序和文件搬到新服务器,再根据报错逐个解决兼容性问题。

依赖版本太老就升级依赖,程序不适配就修改程序,配置不兼容就重新调整。等服务能够运行以后,再清理不需要的文件,继续调试和联调。

AI 一直在分析错误、修改程序和给出下一步建议,迁移工作看起来也一直在推进。

但当被问到项目状态时,得到的回答经常是:

AI 还在跑。

接下来的信息,也主要是对 AI 输出内容的转述:现在遇到了什么报错,AI 正在修改什么,准备升级哪些依赖。

如果进一步追问:

为什么会出现这个问题?

为什么必须在迁移过程中升级这个依赖?

这项修改会带来什么影响?

当前距离迁移完成还有多远?

如果失败,准备如何回滚?

很多问题就没有清晰的答案。

这件事让我产生了一个疑问:

AI 已经如此强大,为什么使用 AI 执行的方案,依然可能很笨?

一个迁移任务,变成了多个项目

这件事表面上是服务器迁移,实际执行的却是:

服务器迁移 + OS 大版本升级 + Runtime 升级 + Dependency 升级 + 老服务改造 + 历史文件清理 + Bug Fix

原本只需要改变一个变量:

AWS → VPS

现在却同时改变了服务器、操作系统、运行时、依赖版本、程序代码、配置、路径和网络环境。

一旦服务出现异常,很难快速判断问题来自哪里。

可能是文件没有迁移完整,可能是配置错误,可能是权限或路径不同,可能是 Ubuntu 版本差异,也可能是 Python、PHP、Node、Java、OpenSSL 或 glibc 的版本变化。

还有可能是某个程序升级以后行为发生了改变,或者原来一直存在的隐藏问题,在新环境中被触发了。

变量一下子增加了很多。

原本应该低风险、可验证、可回滚的迁移,主动变成了一次复杂的复合变更。

生产环境的变更有一个很朴素的原则:

一次尽量只改变一个维度。

Migration 不等于 Modernization。

迁移是迁移,系统升级是系统升级,程序重构是程序重构,清理技术债又是另一个项目。

这些工作最终都可以做,但不应该全部绑在同一次切换中完成。

因为工程风险不是简单相加,很多时候更接近相乘。

先复制一个能够工作的系统

更稳妥的思路,是先在旧环境中收敛迁移范围。

哪些服务真的还在运行,哪些端口仍然有流量,哪些 cron、systemd 或 supervisor 任务仍然有效,哪些目录还有读写,哪些文件和服务已经废弃。

对于确认不再需要的内容,可以先在旧环境中下线、隔离或清理,并观察是否产生影响。

旧的生产环境本身就是最可靠的 reference environment。

它现在能够正常运行。每减少一个东西,都可以立即验证是否影响服务。如果出现问题,也更容易判断是哪一步造成的。

完成清理以后,再尽可能冻结当前能够工作的运行环境。

Docker 是其中一种可行的方式。

第一阶段的目标不是升级程序,也不是让 Dockerfile 看起来多么现代,而是尽可能复刻老服务当前可以正常工作的 userland 环境。

老版本的 PHP、Python、Node、Java 和依赖库,能不动就先不动。

第一目标只有一个:

Behavior parity。

先证明服务在容器中能够按照原来的方式运行,再把容器迁移到新的 VPS。

这样新的宿主机主要负责 kernel、Docker runtime、网络和存储。只要容器能够正常运行,Ubuntu 16.04 到 Ubuntu 22.04 的大部分 userland 差异,就不会直接进入本次迁移的关键路径。

当然,Docker 也不能解决所有兼容性问题。

如果老程序依赖特殊内核模块、硬件设备、特定 syscall、复杂的 host network 或特殊的 systemd 行为,容器化同样需要评估。

真正重要的不是“所有老服务都必须使用 Docker 迁移”,而是背后的原则:

先复制一个能够工作的系统,再优化它。

不要一边搬家,一边装修

服务器迁移,本质上是把一套正在工作的环境从一个地方搬到另一个地方。

理想的结果不是让它在搬家过程中变得更新、更先进,而是让它到达新环境以后,仍然能够按照原来的方式工作。

这有点像把一批办公电脑从使用 220V 电压的办公室,搬到使用 110V 电压的新办公室。

一种做法是,不提前整理,把电脑、显示器、键盘、坏鼠标和废弃打印机全部搬过去。到了新办公室以后,发现电压和环境不同,于是把每台电脑拆开,逐个更换电源、升级系统、安装驱动。

装着装着,又发现某台旧电脑上的软件无法运行,于是开始修改软件。

结果原本只是一次搬家,却变成了设备清理、电路改造、硬件升级、系统升级、驱动适配和软件重构。

所有事情都在同时发生,新办公室自然迟迟无法恢复工作。

另一种做法是,先在原办公室确认哪些设备仍然需要,把不再使用的外设清理掉。确认剩下的设备能够正常工作以后,把整套工作环境——电脑、连接方式和供电关系——尽可能原封不动地装箱。

到了新办公室,只需要在统一的供电入口解决新旧环境之间的适配问题,而不是把每台电脑分别拆开改造。

更合理的顺序应该是:

先准备好新环境,再迁移现有系统并恢复服务。
等运行稳定以后,再升级依赖、改造程序、清理技术债。

新环境可以提前准备,老系统不必在搬迁途中完成改造。

不要一边搬家,一边装修。

每个答案都可能是对的,整条路线却是错的

程序在 Ubuntu 22.04 上报错,AI 分析错误并建议升级依赖。

依赖升级以后出现新问题,AI 再修改代码。

代码修改以后无法联调,AI 又继续分析日志、调整配置。

如果只看每一个局部问题,AI 给出的答案可能都有道理。

但更高一层的问题是:

为什么一次服务器迁移,需要解决这些问题?

如果运行环境能够被一起封装和迁移,那么其中大量问题根本不应该出现在 migration critical path 里。

AI 很擅长回答:

这个报错应该怎么解决?

但它未必会主动停下来追问:

这个报错为什么需要在本次项目中解决?

是不是从一开始,就选择了一条不必要的路线?

AI 会根据人提供的目标、上下文和当前问题继续向前推进。

人给它一个局部问题,它就努力解决这个局部问题。解决以后出现下一个问题,它再继续解决下一个问题。

这会产生一种强烈的推进感:

报错 → 问 AI → 修改 → 新的报错 → 再问 AI → 再修改。

人一直在操作,AI 一直在输出,日志不断刷新,代码不断变化,所以看起来项目始终在前进。

但忙碌不等于接近目标。

AI 可能帮助解决了五十个问题,而其中四十五个问题,原本就不应该被创造出来。

AI 降低了解决问题的成本,却没有自动提高定义问题的能力。

更危险的是,解决问题变得越容易,人就越可能沿着错误路线继续走下去。因为无论遇到什么障碍,AI 都会很快给出下一个可以尝试的动作。

错误路线因此变得更容易坚持。

“AI 在跑”不是项目状态

当一个项目被问到进度时,真正需要说明的是:

这些才是项目状态。

“AI 在跑”只能说明一个工具正在工作。

它和“程序正在编译”“脚本正在执行”“文件正在复制”没有本质区别。

它不能说明项目是否正在接近目标,也不能说明当前路线是不是正确。

AI 输出了什么,同样不等于项目负责人得出了什么结论。

如果一个人只是把问题输入给 AI,再把 AI 的答案转述给其他人;当别人继续追问时,他又需要回去询问 AI,那么他并没有真正进入问题。

他只是变成了人和 AI 之间的一层接口:

问题 → 输入给 AI → AI 输出 → 转述输出。

如果这条链路中没有理解、验证、判断和取舍,那么人的价值只剩下信息搬运。

而信息搬运,恰恰是 AI 最容易替代的工作。

AI 可以成为 Agent,人不能退化成接口。

AI 放大的,是人原来的工作方式

一个人工作了很多年,可能处理过大量故障,熟悉很多命令,也很擅长根据报错排查问题。

但这不一定意味着他同时具备:

Troubleshooting 和 change design 是两种不同的能力。

前者是在问题出现以后解决问题,后者是在项目开始以前,尽可能避免不必要的问题出现。

AI 会进一步放大这两种能力之间的差异。

具备系统思维的人,会使用 AI 调研资料、验证假设、比较方案、寻找风险,并提高执行效率。

习惯线性执行的人,则可能把报错不断交给 AI,再按照输出一步步修改。

两个人都在使用 AI,但 AI 放大的不是同一种能力。

AI 不会自动让一个人的方案变聪明,它更可能先把这个人原有的思考方式放大。

AI 也不会因为使用者拥有很多年工作经验,就自动把经验转化成系统判断。

重复经历问题,不等于理解问题。

熟练解决故障,也不等于能够设计一个尽量不产生故障的方案。

问题不只出在执行者

这个案例也不能只归结为某个人没有正确使用 AI。

如果一个项目可以长时间用“AI 在跑”汇报进度,错误的技术方案也可以持续执行,那么组织的管理方式同样需要反思。

在执行之前,是否做过真正的方案评审?

是否明确了本次迁移的目标和边界?

是否区分了必须完成的迁移,与可以延后处理的升级和改造?

是否要求负责人说明风险、验证标准和回滚计划?

在执行过程中,管理者询问的是“做了多少事情”,还是“距离目标还有多远”?

AI 让执行过程变得更快,也让过程看起来更加复杂。代码、日志、修改记录和中间结果可以源源不断地产生。

如果管理仍然只看工作量和表面进度,就很容易把 AI 制造出来的繁忙误认为项目进展。

因此,AI 时代的方案评审和进度管理,反而需要更加关注几个基本问题:

目标是什么?

为什么选择这条路线?

哪些问题必须解决?

哪些问题根本不应该进入当前项目?

用什么证据证明正在接近目标?

最终由谁作出判断并承担结果?

AI 可以参与分析,也可以提出建议。

但这些问题不能只由 AI 回答。

项目负责人必须理解答案、验证答案,并形成自己的结论。

AI 可以代劳,但不能替人负责

AI 可以写脚本、分析日志、修改配置、生成 Dockerfile、排查报错,甚至可以作为 Agent 自主运行很长时间。

执行层面的许多工作,都可以交给 AI。

但任务可以交给 AI,理解不能交。

操作可以交给 AI,判断不能交。

答案可以由 AI 生成,结论必须由人形成。

工作可以由 AI 完成,责任仍然需要由人承担。

用了 AI,为什么方案依然很笨?

因为 AI 能够提高当前路径上的执行效率,却不会自动保证当前路径是正确的。

方向正确,它会让人更快到达目标。

方向错误,它也会让人更快、更有信心地走向错误。

AI 让执行越来越便宜,也让判断变得越来越重要。

AI 在跑的时候,人更不能停止思考。

继续阅读

评论 · 加载中

正在加载评论……

发表回复

您的邮箱地址不会被公开。 必填项已用 标注