双机开发运维计划:角色、冲突、容灾与备份
确认后再开发。本计划回答:哪台是主开发机、如何避免双机同时改解析器冲突、能否在本机开发远端任务、宕机如何检测与恢复、重启后如何恢复开发、记忆与交互数据如何备份。
一、双机角色定位(没有唯一“主开发机”)
| 角色 | 站点 | 负责内容 | 操作入口 |
|---|---|---|---|
| 引擎主节点 | cgajs.com |
parser、geometry operations、runtime、NL2CGA 生成模型、IDE 核心、dist-stable | SSH 到 cgajs.com 或在 rulepackage.com 通过 cga-ssh 代理 |
| 控制 / 资产主节点 | rulepackage.com |
CGA 资产仓库、Omega 黄金测试、Marketplace、共享记忆中心、跨站状态面板 | 直接登录 rulepackage.com |
二、避免双机同时改解析器冲突
原则:每个目录只有一个“写入主节点”。
/www/wwwroot/cgajs-engine/src:只有 cgajs.com 可写;rulepackage.com 上的副本为只读同步副本。/www/wwwroot/marketplace.rulepackage.com/files、nl2cga-service/library:只有 rulepackage.com 可写;cgajs.com 上的副本为只读缓存。/www/wwwroot/shared-memory:两站均可写,但改完必须sync.sh push,先 pull 再改。
2.1 具体防冲突措施
| 措施 | 实现方式 |
|---|---|
| 目录只读标记 | 在 rulepackage.com 的 cgajs-engine/src 目录放 READONLY_ON_THIS_SERVER.md,并在 .bashrc 登录时提示;权限设为 555(root 仍可写,但有明显阻力)。 |
| git hook 拦截 | 在 rulepackage.com 的 cgajs-engine 仓库加 pre-commit hook:如果检测到 src 目录有新提交且非 sync 脚本触发,则警告并拒绝提交。 |
| 同步方向锁 | scripts/sync-engine-to-rulepackage.sh 只从 cgajs.com → rulepackage.com;scripts/sync-assets-to-cgajs.sh 只从 rulepackage.com → cgajs.com。 |
| 共享任务锁 | tasks.json 中每个活跃任务标记 owner(cgajs.com / rulepackage.com / both),避免同一个人在两台机器上同时改同一任务。 |
2.2 如果确实需要在 rulepackage.com 上“开发解析器”怎么办?
方案:通过 SSH 在 cgajs.com 上开 Kimi 会话,而不是在 rulepackage.com 本地改源码。
# 在本机(rulepackage.com)直接启动 cgajs.com 上的 Kimi 会话 ssh -t root@8.216.94.109 'cd /www/wwwroot/cgajs-engine && kimi -C' # 或者只执行一条远程命令 ssh root@8.216.94.109 'cd /www/wwwroot/cgajs-engine && npm test'
我们会在 rulepackage.com 的 /root/.bash_aliases 里预设别名:
alias cga-ssh='ssh root@8.216.94.109' alias cga-kimi='ssh -t root@8.216.94.109 "cd /www/wwwroot/cgajs-engine && kimi -C"' alias cga-test='ssh root@8.216.94.109 "cd /www/wwwroot/cgajs-engine && npm test"'
三、在本机开发 cgajs.com 远端任务
可以。三种模式任选:
- 代理模式(推荐):在 rulepackage.com 上输入命令,通过 SSH 在 cgajs.com 执行,结果回显到当前终端。
- 远程 Kimi 模式:
ssh -t root@8.216.94.109 'kimi -C',完全进入 cgajs.com 的 Kimi 环境。 - 共享任务模式:在 rulepackage.com 上写好任务描述和修改意图,更新
tasks.json,然后ssh到 cgajs.com 执行。
所有修改会落盘在 cgajs.com,然后通过 engine sync 脚本同步回 rulepackage.com 进行测试。
四、宕机检测与恢复
4.1 检测机制
每台服务器运行一个 watchdog 脚本(systemd timer 或 cron 每分钟一次):
- 检查对方 HTTP 200:
curl -fsS https://rulepackage.com/api/v1/status >/dev/null 2>&1 curl -fsS https://cgajs.com/api/v1/status >/dev/null 2>&1
- 检查对方 SSH 可达:
ssh -p 2222 root@localhost hostname # 在 cgajs.com 上检查 rulepackage.com ssh root@8.216.94.109 hostname # 在 rulepackage.com 上检查 cgajs.com
- 把结果写入
/www/wwwroot/shared-memory/health/{hostname}.json。
4.2 发现宕机后的行为
| 故障场景 | 检测结果 | 自动动作 | 人工动作 |
|---|---|---|---|
| cgajs.com 宕机 | rulepackage.com 无法访问 cgajs.com | 在 shared-memory 写入 incidents.json;Omega/资产同步暂停;页面显示“引擎维护中”。 |
登录云控制台重启 / 修复 cgajs.com;恢复后自动 pull 最新 shared-memory。 |
| rulepackage.com 宕机 | cgajs.com 无法访问 rulepackage.com | cgajs.com 继续用本地缓存的 corpus/marketplace;写 incidents.json;通知管理员。 | 重启 rulepackage.com;恢复后 cgajs.com 自动补齐缺失的 golden cases / corpus。 |
| 网络分区(双方互相不可见) | 双方都认为对方宕机 | 各自继续服务自己的权威域;不自动切换主节点,避免脑裂。 | 排查网络;恢复后按时间戳合并 shared-memory,冲突时人工裁决。 |
五、服务器重启 / 开发中断恢复
之前出现的问题:服务器重启导致 Kimi CLI 未完成的 tool call 状态损坏,进入会话报错。
5.1 预防措施
- 所有长期任务用
screen或systemd运行,而不用前台 Kimi 进程。 - 关键状态持久化到
/www/wwwroot/shared-memory/,至少每 5 分钟或每次重要操作后sync.sh push。 - 反向 tunnel 由 systemd
shared-tunnel.service管理,开机自启、断线重连。
5.2 重启后恢复脚本
在 /root/kimi-recover.sh 中实现:
#!/bin/bash set -e echo "[recover] restart shared-tunnel..." systemctl restart shared-tunnel || true echo "[recover] pull shared-memory..." cd /www/wwwroot/shared-memory && ./sync.sh pull echo "[recover] check kimi sessions..." ls ~/.kimi-code/sessions/ 2>/dev/null || true echo "[recover] backup and clean corrupt wires if any..." mkdir -p ~/.kimi-code/sessions.bak cp -r ~/.kimi-code/sessions ~/.kimi-code/sessions.bak/$(date +%s) 2>/dev/null || true # 可选:检测并删除 0 字节或损坏的 wire 文件 find ~/.kimi-code/sessions -type f -size 0 -delete 2>/dev/null || true echo "[recover] done"
重启后先执行 /root/kimi-recover.sh,再登录 Kimi。
5.3 会话恢复策略
- 如果只是 SSH 断开:screen 保留会话,重新登录后
screen -DR kimi自动恢复。 - 如果是服务器重启:screen 会话丢失,依赖 shared-memory 中的任务/memory 重建上下文。
- 如果 wire 损坏导致 Kimi 报错:运行
kimi-recover.sh清理;必要时用kimi --resume session_id或新建会话。
六、中间层记忆与交互数据备份
6.1 中间层记忆数据
| 数据 | 位置 | 备份方式 | 副本数 |
|---|---|---|---|
| 共享记忆 / 任务 / updata | /www/wwwroot/shared-memory/ |
git 仓库:bare 在 cgajs.com,working copy 在两台机器 | ≥3(cgajs.com bare + 两站 working copy) |
| AGENTS.md / 项目约定 | shared-memory/AGENTS.md + 各项目根 AGENTS.md | 随 shared-memory 同步;项目根 AGENTS.md 手工同步 | ≥2 |
| API 数据库 | cgajs-api / nl2cga-service 数据库 | 每日 dump 到 /www/wwwroot/backups/db/,rsync 到另一台机器 |
≥2(本地 + 对端) |
| Omega golden cases | cgajs-engine/tests/golden/omega-uploads/ |
rulepackage.com 权威;每晚 rsync 到 cgajs.com | ≥2 |
| Marketplace 文件 | marketplace.rulepackage.com/files/ |
rulepackage.com 权威;每晚 rsync 到 cgajs.com | ≥2 |
6.2 交互数据(Kimi 会话日志)
Kimi CLI 的实时 session wire(~/.kimi-code/sessions/)不建议双机实时同步:
- 文件大、变化频繁、包含临时状态,同步容易冲突。
- 双机同时操作同一个 session 会导致状态混乱。
推荐做法:
- 只备份日志:
~/.kimi-code/logs/每日压缩到/www/wwwroot/backups/kimi-logs/{hostname}/,并 rsync 到另一台机器。 - 关键上下文落到
shared-memory/memory.md和tasks.json,这才是需要双机共享的“记忆”。
6.3 异地备份(可选增强)
把 shared-memory 这个 git 仓库再 push 到一个私有 GitHub / Gitee / 阿里云 CodeUp 仓库,形成异地第三副本。
cd /www/wwwroot/shared-memory git remote add mirror https://token@github.com/your-org/cga-shared-memory.git git push mirror master
七、实施计划(等你确认)
| 阶段 | 内容 | 预计时间 |
|---|---|---|
| P0 |
明确双机角色;在 rulepackage.com 添加 cga-ssh/cga-kimi/cga-test 别名;
在 cgajs-engine/src 目录放 READONLY_ON_THIS_SERVER.md 并设权限 555;
创建 /root/kimi-recover.sh 和 systemd shared-tunnel 健康检查。
|
1 天 |
| P1 |
部署双机 watchdog:每分钟互相 ping HTTP/SSH,写入 shared-memory/health/;
宕机时写 incidents.json 并发送告警(邮件/钉钉/webhook)。
|
2 天 |
| P2 | 数据库 dump 脚本 + cron;Omega / Marketplace 文件 nightly rsync; Kimi 日志每日备份到对端。 | 2 天 |
| P3 | 把 shared-memory 推送到私有 GitHub/Gitee/CodeUp 异地镜像; 做一次真实故障演练(重启 cgajs.com,验证 rulepackage.com 检测与恢复流程)。 | 2 天 |
八、一句话总结
没有唯一主开发机:cgajs.com 是引擎主节点,rulepackage.com 是控制与资产主节点。
你可以在 rulepackage.com 上通过 SSH 开发 cgajs.com 的远端任务;
双机通过共享 git 仓库、API、watchdog 和备份脚本保持同步与可恢复。
关键记忆落在 shared-memory,Kimi 会话日志只本地备份不上链,避免冲突。