夜雨聆风学习资料网

ARTICLE · 1131240

小 VPS 撑不住了:我是怎么把整个 AI 助手搬到新主机的

小 VPS 撑不住了:我是怎么把整个 AI 助手搬到新主机的

先说清楚对象。Hermes 是一个可以自托管的 AI 助手 —— 你把它装在自己的服务器上,用 Telegram 这类聊天工具指挥它干活。它和普通脚本最大的区别是「会长」:技能、记忆、会话记录都会随时间沉淀下来。

我这台 Hermes 住在一台 2 核 CPU 、 2.4G 内存、 43G 磁盘的小 VPS 上。

半年前它还很轻。现在它长成了这样: 385 个技能文件、 4439 段会话记录、 3 个 Telegram 机器人,外加一条每天早上自动跑的信息采集管线,和一个几千篇笔记的知识库。与此同时,这台机器的磁盘占用到了 98%,负载常年在 1.7 以上。

换机器这件事,表面是运维小活,实际是道陷阱题。

重装一遍再手工填配置? 这套系统里有 400 多处写死的绝对路径,漏掉任何一处,对应功能就静默失效 —— 它不报错,只是不工作。

直接打包搬过去? 状态数据库用的是 WAL 模式(可以理解成「先记流水账、再落正式账本」),一边写一边拷贝,拿到手的很可能是一个损坏的库。

最后我把这次迁移做完了,也留下了一份 18 个坑的清单。这篇先把结论给你,再讲坑,最后说这套东西怎么复用。

一、结论:难点从来不是「搬文件」

文件同步工具谁都会用。整机迁移真正的风险,全在看不见的地方。

第一类,硬编码路径。 技能脚本、定时任务、服务定义里到处是绝对路径。这意味着新机器的家目录必须同名,否则一个复制任务就变成了几百处改写。仅仅确认这一个前提,就决定了整个方案的设计方向。

第二类,进程内存里的状态。 路由表、调度器锁、会话索引,这些东西不在磁盘上,只活在进程里。两台机器同时跑同一个机器人,会互相抢消息;同时写同一个知识库,会产生冲突。

第三类,新旧环境的差异。 时区不同,定时任务就会在错误的时刻触发;新机器镜像自带的配置,可能悄悄覆盖掉你的改动。

把这三类管住,迁移就退化成一次普通的文件同步。

二、做法:分三层,走五步

先分层。 别按文件大小分,按「重建成本」分:

•A 层 · 重建不了的:配置、凭据、技能、会话、知识库、记忆库。必须逐字节搬,约 4.4G 。
•B 层 · 能重装但很贵的:运行时、命令行工具链、浏览器内核。重新装一遍再重新调试的代价,远高于直接传输,约 9.4G 。
•C 层 · 可选的:冷备份、停掉的项目、旧检查点。按需决定。

再分阶段。 核心目标是把停机窗口压到最短:

阶段
做什么
停机
P0
新机初始化:时区、软件包、字体、浏览器内核
无
P1
不停机预同步
,可反复跑,每次只传增量
无
P2
停掉写入者,做一致性快照,传最后的增量
有
P3
装服务、启动、验证
有
P4
全链路验证
—
P5
旧机原样保留,作为回滚窗口
—

因为 P1 已经把 99% 的数据提前搬完,真正需要停机的只有最后几分钟。

两条铁律,违反任何一条都会直接坏事:

1.同一个消息机器人,绝不能由两台机器同时轮询。 切换只能是「停旧 → 启新」的单向动作。
2.状态数据库必须用 sqlite3 .backup,不能 cp。 WAL 模式下直接复制会拿到不一致的镜像。

三、六个最值得说的坑

十八个坑里,这六个最有代表性。

① 清单按目录建,就一定会漏

我按助手的安装目录列了迁移清单。结果漏掉了一个放在家目录下、被 shell 启动脚本引用的密钥文件。

症状很隐蔽:每次登录都多一行「找不到文件」,而依赖这些环境变量的命令行工具会静默失去凭据 —— 不报错,就是连不上。

教训:清单要按「谁引用谁」来建,从启动脚本反向扫描,而不是正向枚举目录。

② 配置文件也讲「先到先得」

给 SSH 做加固时,我写了一个配置文件,把「只允许密钥登录」写进去。命令返回成功,看起来一切正常 —— 直到我用生效值复查,发现密码登录还开着。

原因有点反直觉: SSH 服务对同一个配置项取第一个出现的值,而配置文件是按文件名字母序加载的。服务器镜像自带的一个文件(名字以 99 开头)里写着「允许密码登录」,排在我新加的文件前面,于是我的改动被静默忽略了。

教训:把它改名成 00 开头,问题立刻解决。顺序敏感的系统里,文件名就是优先级。

③ 验证方法的假阳性

我想确认「密码登录是否已被关闭」,用一个非交互模式去连接 —— 连接失败,我一度以为加固成功了。

后来才想明白:在那个模式下,客户端本来就不会尝试输密码,所以它必然失败。这个结果和服务器允不允许密码登录毫无关系 —— 它证明的是客户端的行为,不是服务器的配置。

④ 外部可达性,不能用本机测

防火墙改完,我在本机连自己的公网 IP ,通了。听起来是个好消息。

实际上,连自己的公网 IP 会回环走本地接口,它只验证了本地放行规则 —— 外部到底能不能连进来,一点都没证明。真正靠谱的做法,是用第三方节点从外部去测。

⑤ 架构会变,脚本会过期

我给一个次要角色装独立服务时,被系统主动拒绝了。原因不是权限,而是新版程序已经改了架构:从「每个角色一个独立进程」改成「一台主机一个进程服务全部角色」。我照着旧拓扑写的脚本,在新版本上根本装不上。

教训:迁移脚本里凡是写死服务清单的地方,都要改成动态枚举 —— 写死的清单一定会漏。

⑥ 失效配置是定时炸弹

从旧机原样搬过来的配置里,有一项是「终端默认工作目录」。它指向的目录半年前就被删掉了 —— 在旧机上它其实早就失效,只是没人碰到。搬过来之后,所有新会话里的命令都以退出码 126 失败。

教训:迁移不只是搬文件,还要复核配置里的引用是否仍然有效。

四、三条能带走的原则

就算你不在做迁移,这三条也用得上。

原则一:清单按引用关系建,不按目录建。 正向枚举目录,你只能看到你想得到的东西;反向扫描引用,你才能看到系统实际依赖的东西。

原则二:凡是「可能把自己关在门外」的操作,都要有自动回滚。 改防火墙、改登录认证这类操作,先做改动前快照,再挂一个定时器:若干分钟后若没人确认,就自动还原。这次我在防火墙和 SSH 两处都用了这个模式 —— 也正是它,让这两步可以放心去做。

原则三:验证要读「生效值」,要看「第三方视角」。 「语法检查通过」是必要条件,不是充分条件;「本机能连」也不等于「外部能连」。这两处误判,这次我都亲身踩到过。

五、交付与边界

这次迁移最后沉淀出一套六个脚本的工具链:初始化 → 差异核对 → 预同步 → 停机切换 → 缺口补传 → 安全加固,再加一份 18 项复盘清单。它们都留在自建知识库的运维目录里,并且已经按这次的教训改过一轮,下次换机器可以直接复用。

适用边界:单机自建的 agent + 自建知识库。如果你需要 7×24 零中断,或者多租户隔离,这套方案不适用 —— 那些场景需要的是集群和真正的容灾,而不是一次文件同步。

最后补一个安全提醒:新机器刚上线的那段时间,通常是最脆弱的 —— 密码登录开着、没有防火墙、没有防爆破。我在加固的第一天就拦到一个正在爆破的地址(累计 175 次失败尝试)。迁移的收尾,不是「服务跑起来」,而是「服务跑起来、并且暴露面收干净」。


参考

•本次迁移的分层清单、五阶段流程与脚本集 —— 自建知识库 03_ops/scripts/migration/
•本次迁移的 18 项复盘清单 —— 自建知识库 03_ops/2026-10-05-Hermes 迁移复盘与脚本改进.md
•Hermes Agent 官方文档 —— https://hermes-agent.nousresearch.com/docs

本文由 AI 辅助创作,作者进行了实测验证和编辑修改。

相关学习资料