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 一律写「远程服务器」。
11 KiB
21 · guest 会话"卡顿 / 断开显示连接中"排查
- 日期:2026-09-10
- 触发:用户报障——在另一台电脑用 guest 账号,每次对话后等几分钟就"断开→连接中",提问要等好一会模型才回复,获取会话信息很慢
- 结论一句话:服务端与模型都不慢(8 轮对话 TTFT 1.0–3.5 s、实例回环 TTFB 2 ms、模型出网 0.3 s、nginx 全部 <5 s);用户看到"看不到流式输出、结果与思考一次性出现"的根因是 nginx 默认
proxy_buffering on把流攒块下发(已修复并 reload)。另外存在两个可消除的干扰项:① 生产实例启用着 HMR(热重载)客户端;② 无关域名流量打进编排器(默认 vhost 误配置)。 - 状态:根因已定位并修复(nginx 缓冲)→ 待用户浏览器复验流式;干扰项 A1/A2 待拍板
TL;DR|结论:guest「卡顿 / 显示连接中」排查:服务端与模型都不慢(TTFT 1.0–3.5 s、实例 TTFB 2 ms、nginx 全 <5 s)。 关键:体感根因 = nginx 默认
proxy_buffering on使流式"一次性出现" + 生产启用 HMR 的干扰(→ 档案 22 的 nginx 修复)。 状态:🔄 已定位;A1 禁 HMR / A2 catch-all 用户已决定暂缓
一、实测证据(全部只读取证,未导出任何对话正文)
| 维度 | 实测 | 判定 |
|---|---|---|
| 每轮 TTFT(turn/start → 首个流式 chunk) | 8 轮分别为 1.0 / 1.8 / 1.3 / 1.6 / 1.6 / 1.7 / 3.5 / 1.7 秒 | ✅ 服务端与模型都快,"等好一会才回复"不是服务端造成 |
| 轮时长 | 19 / 118 / 291 / 30 / 64 / 46 / 36 / 49 秒(长轮 = 多步工具调用,正常) | ✅ 无异常 |
| 工具调用 | 95 次,平均 2.3 s,最慢 79.3 s / 44.2 s(个别命令本身耗时) | ✅ 正常 |
| 会话规模 | 8 轮、12 条 user/message、3268 行事件、1.0 MB(压缩) | ✅ 无膨胀(档案 14 H3 保留期可继续缓做) |
| 实例自身 HTTP | 回环 ttfb=0.002s、CPU 7.1%、RSS 276 MB / 512 MB 上限 |
✅ 实例健康 |
| 实例 → 模型 API 出网 | DNS 1.3 ms / TCP 3.9 ms / TLS 17 ms / TTFB 0.30 s | ✅ 出网无碍 |
| nginx(guest 子域) | 732 请求:594×200、24×401、1×404、1×302,全部 <5 s | ✅ 边缘不慢 |
| 24h 内崩溃 / 熔断 / idle-reap | 0 条(新增的 [crash-restart] 也无记录) |
✅ 实例没被反复重建 |
| 系统资源 | 内存 636/1870 MB、可用 1234 MB、负载 0.08、0 次 OOM | ✅ 无资源压力 |
会话时序里最大的几个间隔(34374 s / 1853 s / 561 s…)全部出现在
turn/end之后,即用户离开后隔很久再提问 → 属正常空闲,不是掉线。
二、根因定位与修复:"看不到流式输出"(2026-09-10 23:00)
用户补充关键症状:"刚才那轮对话看不到流式输出,结果和思考过程都是一下显示的" → 指向中间代理缓冲。
| 跳 | 检查 | 结果 |
|---|---|---|
| 应用层 | dsh 是否发 X-Accel-Buffering: no(若发则 nginx 自动不缓冲) |
❌ 未发(全包 grep 无命中) |
| 编排器代理 | src/supervisor/proxy.ts 转发方式 |
✅ 正确流式:upRes.pipe(reply.raw)、WS 走 upgrade 隧道,不缓冲 |
| 传输形态 | 客户端用 WebSocket 还是 HTTP 流 | guest 子域 101 计数 = 0(全站 159 条 101 属其他页面)→ 聊天走 HTTP 流式,正受 nginx 缓冲影响 |
| 前面还有没有一层 | nginx 日志真实客户端 IP(是否 Cloudflare) | 125.85.124.119 / 113.248.166.66 / 154.40.35.3 → 无 CF 段,单层 nginx |
| nginx 配置 | nginx -T 全局搜 proxy_buffering |
❌ 只有 proxy_send_timeout 60,没有任何 proxy_buffering off → 默认 on 生效 ⇒ 流被攒成大块 |
修复(已执行):在两个 443 站点块(主域 + 通配子域)的 location / 增加:
proxy_buffering off; # 关键:流式响应逐块透传
proxy_cache off; # 避免任何缓存介入
proxy_send_timeout 3600s; # 与 proxy_read_timeout 对齐
执行与验证:备份 → 写配置 → nginx -t 通过 → nginx -s reload → 生效确认(nginx -T | grep -c "proxy_buffering off" = 2)→ https://dsh.alotbuy.com/login.html 200、编排器直连 200。
回滚副本:/www/server/panel/vhost/nginx/dsh.alotbuy.com.conf.bak-20260910-2300-pre-buffering(改动前原文,56 行)。
⚠️ 宝塔面板注意:在面板里保存/修改站点配置会按模板重写该 vhost,可能抹掉这 3 行 → 若流式又变回"一次性显示",先检查这 3 行是否还在。
三、两个可消除的干扰项(待拍板)
① 生产实例启用了 HMR(热重载)客户端 —— 头号嫌疑
- 证据:
dsh-web-app/cordis.patch.yml第 148-149 行挂着- id: client-hmr / name: '@deepseek-ai/dsh-client-hmr'→ 每个实例都启用;其客户端持续请求/plugins/events。nginx 记录该路径在 guest 子域上以 ≈65 s 间隔出现(21:43:38 → 21:44:43 → 21:45:48 …),并夹杂 401(21:45:53)与 302(22:39:36,实例未运行时的守卫跳转)。 - 影响:HMR 是开发期热重载能力,生产环境无用;但它会周期性建立/重试一条通道,UI 上很可能就是"连接中"的来源,并且每次实例重启后都会产生 401/302 重试噪音。
- 建议修复(低风险、可回滚):在 profile patch 层按档案 09 已实证的手法禁用该行:
生效需重启实例;先在 admin 或 guest 单个实例验证(页面功能是否正常、
- id: client-hmr name: '@deepseek-ai/dsh-client-hmr' disabled: true/plugins/events请求是否消失)。
② 无关域名流量打进编排器(默认 vhost 误配置)
- 证据:编排器 24h 收到的 Host 分布 —— evertwins.com 880 次、裸 IP
47.77.182.89640 次、www.evertwins.com307 次、wp./staging.evertwins.com各 95 次;而本机没有这些域名的 vhost 文件。 - 成因:nginx
include /www/server/panel/vhost/nginx/*.conf顺序加载,未显式default_server时第一个 server 块即该端口默认站点,我们的 dsh vhost 恰成默认 → 所有未匹配 Host(含扫描器、/.env探测)都被转进业务进程。 - 影响:无关流量与扫描落在业务进程上;访问这些域名会看到 dsh 登录页(品牌混淆)。
- 建议修复:加一个 catch-all 默认站点(
return 444,或server_name _;+ 444)并nginx -t校验;约 1 分钟,可回滚。
四、还需客户端侧取证
服务端已能证明"轮次一旦开始就很快",无法从服务端看到"用户按下发送 → 消息抵达服务端"之间的耗时。请在有问题的电脑上:
- 打开 DevTools → Network,复现"连接中"的瞬间,看:
/api/session/prompt的 Waiting(TTFB) 与是否长时间 pending;- 是否有 WebSocket/EventSource 反复重连(
/plugins/events、/api/...101/未完成); - Console 是否有 401 / 断线报错。
- 记录该电脑的网络环境(是否走 VPN/代理、Wi-Fi 信号、运营商)——"网络很卡"的体感与 401 重试可能叠加。
- 若 DevTools 显示
/api/session/list等请求本身很快而 UI 仍"卡",则属前端渲染/长轮次等待,另案处理。
五、待拍板
| # | 措施 | 风险 | 需要 |
|---|---|---|---|
| A1 | 禁用 client-hmr(profile patch,含 admin/guest 全量或先单例) |
低(生产无用;可回滚=删行) | 需重启实例 |
| A2 | 修默认 vhost:加 catch-all return 444 |
低(仅影响未匹配域名) | nginx -t + reload |
| A3 | 客户端 DevTools 取证(用户侧) | — | 用户在问题电脑操作一次 |
| — | ✅ 已完成(2026-09-10 23:00,见 §二) |
六、"刷新后载入历史会话要几分钟"排查与优化(2026-09-10 23:15)
新症状:刷新后载入历史会话要几分钟,体感"网络很卡"。
取证(nginx 访问日志解析,4000 行窗口内 guest 子域 823 个请求):
| 发现 | 数据 |
|---|---|
| 单次刷新要下载一个巨大的插件 bundle | GET /plugins/??<45 个 client.js 拼接>&rev=<hash> → 实发 980 KB / 930 KB(含 dsh-client-hmr、typert-registry、api-gateway、~30 个 dsh-client-ui-* 面板) |
| 另有哈希静态资源 | /assets/vendor-CCJJTK99.js = 209 KB |
| 大量小 API 轮询(每次刷新都打) | agentPresets/list 131、commands/list 105、modelCatalog 78、syncInspectManifest 76、subagents/list 73、session/list 68 … |
根因(两条叠加):
- 反代响应未被 gzip 压缩:全局
gzip_proxied只列了expired no-cache no-store private auth,不含any→ dsh 反代出来的 JS/JSON 大多不满足条件 → 那个 ~930 KB 的 bundle 以未压缩体积下发(日志$body_bytes_sent即实发字节,若压缩过应是 250 KB 量级)。 - 哈希资源无长缓存:
/assets/*与/plugins/*&rev=*每次刷新都可能重新拉取 ~1.2 MB。
叠加 200+ 次小请求的往返延迟,在链路质量差的电脑上就表现为"几分钟"。
优化(已执行,档案 21 · 2026-09-10 23:15):在 dsh vhost 两个 443 站点块中
location /增加gzip_proxied any;(放开反代压缩)- 新增
location ~* ^/assets/→ 同代理参数 +gzip_proxied any;+expires 30d(哈希文件名 → 可长缓存)
执行:备份(*.bak-YYYYMMDD-HHMM-pre-gzip)→ 写配置 → nginx -t 通过 → reload → 生效确认(gzip_proxied any ×4、/assets/ 长缓存块 ×2)→ 主域 200。
预期效果:那个 ~930 KB bundle → 约 250 KB(gzip 后);重复刷新时 /assets/* 走浏览器缓存。
验证方法:用户刷新后,取该请求的 $body_bytes_sent 对比 —— 预期从 ~930 KB 降到 250–300 KB 量级。
仍待排查(若压缩后依旧慢):① 该电脑链路本身(建议本地测速 / 是否走 VPN);② 每次刷新的 200+ 次小请求往返(属客户端行为,受 R2 限制不能改官方 dsh,只能靠降 RTT 或减少刷新)。
七、红线遵守
- 排查全程只读:仅
ps/free/journalctl/nginx 日志/会话文件解压统计,未导出、未展示任何对话正文(分析器只输出时间戳与事件类型)。 - 建议项不触碰 R1(不升级 dsh)与 R2(不改官方主程序);A1 走 profile patch 层官方机制,A2 仅改 nginx 站点配置。