Files
dsh_shenxian/dsh-server-docs/04-调整方案/94-实例内存口径定案.md
T
admin 5ad755116e chore(docs): 文档库并入代码仓(R4 选 a)+ 索引/台账跟进
1) dsh-server-docs/ 从工作区(原 E:\...\aliyun-dsh-server\dsh-server-docs)**整体并入本仓**,
   保留目录名 ⇒ 仓库内 dsh-server-docs/... 的相对引用天然继续有效;旧目录(含其 .git)已归档到
   工作区 _中间产物_待清理/,未随本提交带入。
2) .gitattributes:新增 `dsh-server-docs/** -text` —— 原文档库是 `* -text` + autocrlf=false,
   必须保持纯 LF,否则会被本仓的 CRLF 规则翻掉。
3) 活引用里的绝对路径已全部改到新位置(docs 的 INDEX / README / scripts / skills + 用户级 skills
   + ~/.workbuddy/settings.json 的 hooks);历史档案(04-调整方案/、archive/)按「只增不改」未动。
   ⚠️ hooks 路径改动需「完全重启会话」才生效(配置是会话启动快照)。
4) 交接单/T08:新增 §16「生产整体切换执行记录」(形态 / 落地动作 / **4 个只有真上线才暴露的真 bug** /
   验收证据 / 回滚命令 / 残留项);台账 T08 行 → 已完成并归档;03-路线图 §二 登记 T08 收尾项。
5) 统一称谓:**「本机」只指跑 WorkBuddy 的开发机**,47 / 106 一律写「远程服务器」。
2026-09-15 18:47:13 +08:00

5.3 KiB
Raw Blame History

94-实例内存口径定案(2026-09-14 落地)

  • 日期:2026-09-14 | 状态:✅ 已上线(平台后端已 npm run build + systemctl restart dshs;插件 0.3.17)
  • 触发:用户裁定 ——「base 448 没问题 max 就是 1024」(此前我在 93 结尾把它列为「需要你定的残留」)

TL;DR 把两侧常量(编排器 instanceMemMb() ↔ 插件客户端 MEM_*)收成一份事实,按用户裁定落地: BASE 448 / MIN 448 / MAX 1024(mcn 成本表保持 128)。 实测生效:admin 384→576、guest 384→448,均在 [448,1024] 内;heapMb 256;两实例 restarts:0。 本机 verify-mem-model 与 npm run verify 首次全绿(此前被这条不一致卡了 4 项红)。


一、为什么必须动(原先的"残留"是什么)

src/supervisor/orchestrator.ts 里有一份别人在途未提交的草稿:BASE 160→448、MIN 384→512、 MAX 1024→1536、dsh-plugin-mcn-suite 128→256;而 poc/business-plugins/lib/client.js 的对应常量还是旧值 ⇒ 本机 verify-mem-model.mjs 4 项红(该脚本的存在意义正是「两份事实漂了」)。

⚠️ 但这组数字直接决定实例 cgroup 配额,属产品决策 ⇒ 我按 R7「只报告、不顺手改」上抛。 用户裁定后我才动手。

二、定案依据(用户裁定 2 项 + 我定 2 项,各有判据)

常量 旧值 草稿 定案 依据
BASE_MEM_MB 160 448 448 用户裁定;且 0.1.5 基座实测 312 MiB,旧值按 0.1.2 的 106~145 估的、严重低估 ⇒ 384 的上限里只剩 72 MiB 给插件,这正是宿主 swap 被吃掉的原因
MIN_MEM_MB 384 512 448 不变量:MIN 必须 ≥ BASE,否则 clamp(raw, MIN, MAX) 的下限失去意义(旧 384 ≥ 旧 BASE 160 成立;抬 BASE 后必须跟着抬)。取「= BASE」是最小的一致值,避免无谓抬升宿主动用余量
MAX_MEM_MB 1024 1536 1024 用户裁定;且编排器头部原有不变量已写明「上限 1024M 是单实例硬顶(宿主 1870M,并发数由 maxIdleInstances + available 决定)」⇒ 草稿的 1536 与宿主容量前提自相矛盾
mcn 套件成本 128 256 128(保持) 无可支撑抬高的实测;反向有证据:装了它的用户在旧 384 上限下一直跑得住 ⇒ 需求 ≤384。而抬它会直接吃宿主余量(1870M / 可用 ≈761M / swap 已用 452M)
univer 512 512 512 未变(有实测:gateway 单进程 ≈390 MB)

三、改动文件

文件 改动
src/supervisor/orchestrator.ts BASE 448 / MIN 448 / MAX 1024 / mcn 保持 128;每条都写了判据注释(含「MIN ≥ BASE」与「MAX 是宿主容量不变量」)
poc/business-plugins/lib/client.js MEM_BASE_MIB 448 / MEM_MIN_MIB 448 / MEM_MAX_MIB 1024(MEM_TABLE 未变)—— 与编排器逐值一致
poc/business-plugins/package.json 0.3.16 → 0.3.17
commit 代码仓 683c4cd(fix(mem): 内存口径定案 …)

四、验证记录

层 命令 / 手段 结果
单测 node --test(5 文件) 48 pass / 0 fail
双端一致 node scripts/verify-mem-model.mjs ✅ 全绿(base 448 / min 448 / max 1024 / headroom 96,插件表逐键一致)
全套 npm run verify ✅ EXIT=0 首次全绿
服务器构建 bash scripts/ci.sh ✅ CI OK(48 pass / 0 fail)
真机配额 /api/dsh/status(临时 session,R4) ✅ admin 576 / guest 448,heapMb 256,均 ≤1024、≥448
宿主余量 free -m 可用 761 → 1267 MiB(重启后实例未常驻)
铺发 ensure-biz-plugins.cjs --all --restart ✅ 两实例均 0.3.17

⚠️ 这次改动顺带纠正了我上一轮的一处误标:A/B 两用户的身份我先搞反了(cce6d1cd 才是 admin、4092b965 是 guest)。 判据 = users 表的 role 列(不是 uuid 顺序、也不是"谁先建")。

五、副作用 / 注意

  • 宿主余量是硬约束:宿主仅 1870 MiB。现两实例上限合计 1024 MiB(原 768),且上限非预留, 实际占用不变;但 maxIdleInstances=4 若真跑满 4 个并发实例,4×448 起 = 1792 MiB 已贴顶 ⇒ 若日后要加并发, 必须先重算这组常量(INSTANCE_MAX 与 MAX_MEM_MB 是耦合的)。
  • 配额的生效时机:instanceMemMb() 在 spawn 时算 ⇒ 已运行的实例不会热变,需重启实例(或等它自然重启)。
  • 文档侧同步:BRIEF.md §隔离(旧写 384 MiB)与 DEPLOY-本部署.md 的 MemoryMax=384M 已改为新口径。 ⚠️ 这两个文件本来就有别人未提交的改动,故未提交(跟着提交会带走别人的活儿,见 95 §五)。

六、回滚

  • 代码:git revert 683c4cd(或把 4 个常量改回 160/384/1024/128)→ npm run build → systemctl restart dshs; 插件侧删 /opt/dsh/artifacts/business-plugins-0.3.17.tgz 后重跑 ensure-biz-plugins.cjs --all --restart(会回落到 0.3.16)。
  • 服务器备份:/opt/dsh/backups/pre-94-20260914-212322/(orchestrator.ts + poc/.../client.js)。
  • 无数据迁移、无 DB 变更。