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 一律写「远程服务器」。
5.3 KiB
5.3 KiB
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] 内;heapMb256;两实例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 变更。