# remote43 运维基线(2026-06-10) ## 1. 目标 这份文档用于回答三件事: 1. remote43 当前到底跑着什么 2. 为什么“更新部署经常看起来成功、实际没切过去” 3. 后续持续运维必须遵守哪些规则 这是当前真相源,优先于零散会话结论。 ## 2. 服务器画像 ### 主机 - Host: `ubuntu@43.155.133.187` - Hostname: `VM-0-16-ubuntu` - OS: Ubuntu / Linux `6.8.0-107-generic` - CPU: 2 vCPU - Memory: 3.6 GiB - Swap: 1.9 GiB - Root disk: 59G, 已用 34G, 使用率 59% ### 当前负载(2026-06-10 09:25 CST 只读巡检) - load average: `3.16 3.39 3.40` - 可用内存仅 `259 MiB` - swap 已使用 `982 MiB` - memory PSI / io PSI 持续非零,存在资源压力 ### 主要监听端口 - `80` / `443` → nginx - `8080` → sub2api host - `127.0.0.1:18190` → CRM ## 4. 当前运行面真相 **最后更新: 2026-06-10** ### CRM 当前状态 - 运行目录: `/home/ubuntu/crm-only-20260602_18190` - 当前进程 PID: `920892` (systemd 管理) - 当前运行命令: `./sub2api-cn-relay-manager-server` - `/proc/920892/exe` 指向: - `/home/ubuntu/crm-only-20260602_18190/sub2api-cn-relay-manager-server` (无 deleted 标记) - Portal Session: `login_enabled: true` ✓ ### CRM 健康与管理接口 - `GET /healthz` → `ok` - `GET /api/packs` + admin token → `HTTP 200` 这表示: - CRM 当前不是完全挂掉 - 问题核心是“部署切换失败”,不是“服务不可用” ### CRM 数据库 - 文件:`/home/ubuntu/crm-only-20260602_18190/sub2api-cn-relay-manager.db` - 当前快速计数(2026-06-10 巡检时): - `hosts = 0` - `logical_groups = 0` - `logical_group_routes = 0` - `user_keys = 0` - `schema_migrations = 17` 注意:当前 DB 已不是“有完整生产业务数据的状态库”,至少在该时点已经接近空库。 ## 4. 当前仓库/部署目录事实 ### 远端 repo - 路径:`/home/ubuntu/sub2api-cn-relay-manager-git-current` - HEAD: `4ec9dad44f6768368c2aa782ed96d36355709823` - `git status --short` 发现: - `?? sub2api-crm-server` 说明: - 远端 repo 不是完全干净 - 存在未纳管二进制残留 ### CRM 目录关键文件 - `.env.crm`:2026-06-09 21:28 更新 - `sub2api-crm-server-gateway`:2026-06-09 21:28 上传 - `sub2api-cn-relay-manager-server`:2026-06-06 10:39 旧文件 - `crm.log`:最新内容只有一条启动失败日志 - `crm.pid`:2026-06-09 21:28 写入 ## 5. 已确认的部署失败根因链 ### 根因 1:旧进程没有真正退掉 证据: - `18190` 被旧进程 `54164` 占用 - 新 bootstrap 之后 `crm.log` 明确报: - `listen tcp 127.0.0.1:18190: bind: address already in use` 结论: - 新进程没有启动成功 - 旧进程继续服务,造成“部署看起来成功、实际没切换” ### 根因 2:deploy_crm_only.sh 不是生产热更新脚本 证据: - `scripts/deploy/deploy_crm_only.sh:138` - `rm -f "$CRM_DB_FILE" "$CRM_LOG_FILE"` - `scripts/deploy/deploy_crm_only.sh:205` - 远端清理时也删除 `REMOTE_CRM_DB_FILE` 结论: - 该脚本会删除 SQLite DB - 它适合“重建栈”,不适合“保状态热更新” ### 根因 3:CRM 启动方式仍然脆弱 证据: - `scripts/deploy/deploy_crm_only.sh:140` - `nohup bash -lc 'set -a; source "$CRM_ENV_FILE"; set +a; exec "$CRM_BINARY"'` 结论: - 这是已知脆弱模式 - 即使这次主要失败是端口占用,这个模式本身也不应继续作为生产标准 ### ✅ 已修复:portal 部署脚本和测试门禁已修正契约 原问题: - `scripts/deploy/deploy_tksea_portal.sh` 曾使用 `$cookie_crm_session` - `scripts/test/test_tksea_portal_assets.sh` 曾断言 `$cookie_crm_session`,并排斥 `$cookie_crm_subject` 修复(本轮完成): 1. `deploy_tksea_portal.sh` 已改为 `$cookie_crm_subject` 2. `test_tksea_portal_assets.sh` 已改为断言 `$cookie_crm_subject` 存在、`$cookie_crm_session` 不存在 3. `nginx.sub.tksea.top.conf.example` 已同步更新 4. 测试门禁已通过:`bash scripts/test/test_tksea_portal_assets.sh` → PASS ## 6. 资源与容量风险 ### 高风险:内存压力 证据: - 机器总内存 3.6 GiB - 可用仅 259 MiB - swap 已用近 1 GiB - Top RSS: - `gitea web` 占用约 `2.45 GiB` RSS 结论: - 当前机器资源最重的不是 CRM,而是 Gitea - remote43 已处于“高内存压力 + 持续 swap”状态 - 这会放大部署时序问题、I/O 抖动、git/编译/解压失败概率 ### 中风险:孤儿/历史进程与残留栈 证据: - 存在 `/tmp/sub2api-crm-static-verify` - 存在多个 `/app/sub2api` - 存在 quarantine / tokens-reef / 临时目录残留 结论: - remote43 不够“单一生产真相” - 存在历史验证栈、遗留进程、临时产物共存 ## 7. 备份与恢复现状 当前看到的备份更多是“人工备份痕迹”,不是制度化备份: - `sub2api-cn-relay-manager.db.bak.20260608_*` - `trusted-subject-backup-20260609_173034/` 缺口: - 没看到定时数据库备份作业 - 没看到统一的保留策略 - 没看到恢复演练记录 ## 8. 未来持续运维规则(强制) ### R1. 生产 CRM 只能走“非破坏性热更新” 禁止: - 删除生产 SQLite DB - 用“重建栈脚本”直接覆盖生产 - 不确认旧 PID 已退出就启动新进程 必须: 1. 记录当前 PID / 二进制 sha256 / DB 文件时间 2. 停旧进程并确认 `18190` 已释放 3. 上传新二进制 4. 启动新进程 5. 验证: - `healthz=ok` - 管理接口 200 - `readlink /proc/$pid/exe` 指向新二进制,且不带 `(deleted)` ### R2. 生产脚本禁止删除 DB 任何生产 deploy 脚本都不得包含: - `rm -f "$CRM_DB_FILE"` - `rm -f "$REMOTE_CRM_DB_FILE"` 如确需重建数据库: - 必须单独命名为 destructive/rebuild 脚本 - 必须显式要求人工确认 ### R3. CRM 必须纳入明确监督器 当前状态: - CRM 不是 systemd service - 只是一个 pidfile + nohup 进程 后续规则: - 生产 CRM 必须迁移到以下二选一: 1. systemd service 2. 明确的进程监督器(且有 status/restart/log 统一入口) 目标: - 避免 `(deleted)` ELF 长期运行 - 避免 pidfile 漂移 - 避免人工 kill/start 时序错误 ### R4. 部署脚本、示例、测试门禁必须共享同一契约 当前关键契约: - trusted subject 来源必须是 `$cookie_crm_subject` - 不能再使用 `$cookie_crm_session` 规则: - 文档改了,deploy script 和 test gate 必须同改 - 任何一个仍保留旧契约,都不允许宣称闭环 ### R5. 每次部署后必须做“三层验证” 1. 进程层 - 监听端口正确 - PID 正确 - `/proc/$pid/exe` 不带 `(deleted)` 2. 控制面层 - `/healthz` = ok - `GET /api/packs` = 200 3. 用户面层 - `GET /api/portal/session` - create/chat/pause/resume/delete 全链路 ### R6. remote43 要建立单一真相目录 建议长期保留: - 一个生产 CRM root - 一个生产 repo root - 一个 runbook 路径 - 一个 backup 路径 禁止长期保留大量含糊用途目录: - 多个临时验证 root 并存 - 不说明用途的 quarantine / tmp 二进制常驻 ### R7. 建立最低备份制度 至少包括: 1. SQLite DB 定时备份 2. nginx site 配置备份 3. `.env.crm` 备份 4. 最近 N 份保留策略 5. 一次真实恢复演练 ### R8. 资源治理规则 - Gitea 当前是最大内存消费者,后续任何“服务器变慢/部署异常”都要先看它 - 当 available memory < 300MiB 或 swap 持续增长时,禁止在 remote43 直接进行重编译/大规模解包 - 生产构建优先本地 build 后上传成品,而不是远端现编 ## 9. 推荐后续动作(按优先级) ### P0 1. 修 `scripts/deploy/deploy_crm_only.sh` - 去掉删 DB - 改成真正 hot-update - 启动后验证新 PID 与新 exe 2. 修 `scripts/deploy/deploy_tksea_portal.sh` - 改成 `$cookie_crm_subject` 3. 修 `scripts/test/test_tksea_portal_assets.sh` - 门禁改成断言 `$cookie_crm_subject` ### P1 4. 为 CRM 增加 systemd service 5. 增加数据库定时备份脚本与保留策略 6. 增加部署后自动 smoke 验证脚本 ### P2 7. 清理 remote43 历史验证残留目录/进程 8. 评估 Gitea 内存占用与迁移/限额策略 ## 10. 当前结论 - remote43 不是“服务挂了”,而是“部署切换机制不可靠” - 生产 deploy 脚本当前不满足持续运维标准 - 未来必须把“部署、监督、备份、门禁、资源治理”五件事制度化,不能继续靠临时脚本和人工记忆