mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-09-20 00:48:00 +00:00
update: 2026-08-11 code review findings + WebUI crash fix & 41s delay analysis (P10-1..P10-5, P4-1..P4-6)
This commit is contained in:
18
plan.md
18
plan.md
@ -44,6 +44,14 @@
|
|||||||
- AUTO 链只有 4 槽,13+ 配置模型不参与 AUTO,且 webui 编辑链后无任何"健康复位"提示。
|
- AUTO 链只有 4 槽,13+ 配置模型不参与 AUTO,且 webui 编辑链后无任何"健康复位"提示。
|
||||||
- 审计文件 jsonl 无限增长(当前 547KB);`AppendAudit` 每事件一次文件 open。
|
- 审计文件 jsonl 无限增长(当前 547KB);`AppendAudit` 每事件一次文件 open。
|
||||||
|
|
||||||
|
### P10 全量代码审查发现(2026-08-11,全部核心文件通读后确认)
|
||||||
|
- **P10-1(高,已确认)`handleSourcesAPI` 无 admin 校验**(api.go:77-123,全方法无 `reqRole` 检查,对比 `handleAdaptersAPI` api.go:21、`handleStatsAPI` api.go:138 均有)→ 任何 user 级 key 可 `GET /api/sources` 读取全部上游**明文 api_key**(`config.Source.APIKey` 带 `json:"api_key"`,config.go:42;GET 分支直接返回 `g.core.Sources()`),并可 POST/DELETE 增删改源配置、篡改路由。**越权最高优先级修复项。**
|
||||||
|
- **P10-2(中,推断)`hasScopeModel` 不剥前缀**(chat.go:219)直接用原始模型串与 scope 比对 → 受限 user key 用 `zen:model` 前缀调用会被误判 403(未实测,待确认修复)。
|
||||||
|
- **P10-3(中,已确认)runtime.json 源无超时**:JSON 源不序列化 timeout,`mergedSources` 后 Timeout=0(无限)→ 生产 4 个源全部无超时;上游假死不返回时请求永久挂起、占满 `max_concurrent` 槽(历史上 2 条 120s `context canceled` 均为客户端主动断开)。补默认超时需注意 `http.Client.Timeout` 对 SSE 流式同样生效,需区分流式/非流式策略。
|
||||||
|
- **P10-4(低)stats.go**:失败请求也计入配额消耗(`aggregateLocked` 无条件累计 tokens);`nhour` 配额按整点小时桶粒度不精确(`WindowTokens` 按桶过滤);user 视角 `Snapshot` 的 `by_status` 仍是全局分布(轻微泄露);`Record` 持 mu 时做文件 I/O(append/rotate),高 QPS 下有锁竞争。
|
||||||
|
- **P10-5(低)scheduler.go**:`Chat`/`ChatStream`/`Image` 重试次数受 `len(cands)` 限制(MaxRetries 超出候选数时无效);`chainDrive` 有界等待期间重跑整档(硬失败会正确 break,可接受)。
|
||||||
|
- **健全项(评审确认)**:TryAcquire 忙不记分、chainDrive 硬失败正确打断等待、探活不污染调度状态、冷却必然到期自愈(无永久黑名单)、`ResolvePinned` 前缀解析(41c9b0e)与超时/退避公式(5s·2ⁿ 封顶 30min)正确。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 二、目标架构(定稿)
|
## 二、目标架构(定稿)
|
||||||
@ -226,4 +234,12 @@ p==nil → 400/404;!TryAcquire → 429 busy(快速失败)
|
|||||||
- [x] **P3-5(2026-08-10)测试**:新增 `stats_test.go`(by_status 断言、轮转→保留上限→Record 路径轮转);gateway 新增 `TestAutoStatesReportChainHealth`(states 契约:失败后 fail_count>0+cooling,PUT 复位归零);`go vet ./...` + `go test ./...` 全绿。
|
- [x] **P3-5(2026-08-10)测试**:新增 `stats_test.go`(by_status 断言、轮转→保留上限→Record 路径轮转);gateway 新增 `TestAutoStatesReportChainHealth`(states 契约:失败后 fail_count>0+cooling,PUT 复位归零);`go vet ./...` + `go test ./...` 全绿。
|
||||||
- [x] **P3-6(2026-08-10)WebUI 右键菜单无法关闭(用户实测)**:根因——`showCtx` 创建菜单后从未赋值 `ctxEl`(`hideCtx()` 恒为空操作),任何路径(点菜单项/点外部/二次右键)都关不掉;补 `ctxEl = w`,优先级页与密钥页共用 `showCtx` 一并修复(这也是最初版本就存在的 bug)。
|
- [x] **P3-6(2026-08-10)WebUI 右键菜单无法关闭(用户实测)**:根因——`showCtx` 创建菜单后从未赋值 `ctxEl`(`hideCtx()` 恒为空操作),任何路径(点菜单项/点外部/二次右键)都关不掉;补 `ctxEl = w`,优先级页与密钥页共用 `showCtx` 一并修复(这也是最初版本就存在的 bug)。
|
||||||
- [ ] **P3-7**:推送 origin → 生产机 pull → `-tags luajit` 全量回归(含 P2-7)→ 部署 `/usr/local/bin/llmsproxy` + 重启 service → 观察。
|
- [ ] **P3-7**:推送 origin → 生产机 pull → `-tags luajit` 全量回归(含 P2-7)→ 部署 `/usr/local/bin/llmsproxy` + 重启 service → 观察。
|
||||||
- [x] **P3-8(2026-08-11)审计回放修复(用户实测)**:重启后统计只剩最后 3000 行≈5.3M tokens,历史 273M 消失、且记录里全是 access 脏行——根因 `LoadAudit`:① 只取文件尾 3000 行(而 92% 行是每 3s 的 access 事件);② access/事件行(type 空)被当请求灌入聚合;③ Scanner 默认 64KB 截断风险。修复:回放**全部真实请求行**进聚合(恢复 totals/配额窗口),仅视图环形缓冲限 maxRecs;跳过 type 空的行;`sc.Buffer` 抬到 16MB。新增 `TestLoadAuditFullReplay`(access/坏 JSON/超大行混合回放断言)。
|
- [x] **P3-8(2026-08-11)审计回放修复(用户实测)**:重启后统计只剩最后 3000 行≈5.3M tokens,历史 273M 消失、且记录里全是 access 脏行——根因 `LoadAudit`:① 只取文件尾 3000 行(而 92% 行是每 3s 的 access 事件);② access/事件行(type 空)被当请求灌入聚合;③ Scanner 默认 64KB 截断风险。修复:回放**全部真实请求行**进聚合(恢复 totals/配额窗口),仅视图环形缓冲限 maxRecs;跳过 type 空的行;`sc.Buffer` 抬到 16MB。新增 `TestLoadAuditFullReplay`(access/坏 JSON/超大行混合回放断言)。
|
||||||
|
|
||||||
|
### Phase 4 — 2026-08-11 WebUI 修复与全量代码审查(今日会话)
|
||||||
|
- [x] **P4-1(2026-08-11)WebUI 聊天"每次回复都失败"(用户实测)**:根因——`sendChat()` 调 `addMsg('assistant', '')` 未传 reason 参数 → `thinkEl`/`hintEl` 为 null → 首个携带 `reasoning_content` 的流式 chunk 到达时 index.html 抛 `Cannot set properties of null`,前端表现为请求失败。修复:`addMsg('assistant', '', true)` + 初始隐藏 think 框;提交 `7647b7d`,已推送并部署生产(服务 active、`/api/status` 正常),`go test ./internal/gateway/...` 通过。
|
||||||
|
- [x] **P4-2(2026-08-11)41s AUTO 延迟归因**:审计 `09:54:42 stream lat=41810 model=deepseek-v4-flash-free src=zen ok=200 pt=17 ct=109`——链上调度仅 ~0.6s(tier1 qijiar 失败 lat=657ms 后顺延),其余 ~41s 为 zen 上游生成耗时(~380ms/token),**非网关调度问题**。
|
||||||
|
- [x] **P4-3(2026-08-11)全量代码审查**:provider.go(812 行)/stats.go(459 行)/scheduler.go(398 行)/registry.go(258 行)/api.go/chat.go/server.go/config 全部通读完毕,确认 P10-1~P10-5(见上)。
|
||||||
|
- [ ] **P4-4**:`handleSourcesAPI` 补 admin 校验(P10-1,一行仿 api.go:21)— 待用户确认后实施。
|
||||||
|
- [ ] **P4-5**:`hasScopeModel` 剥前缀比对(P10-2)— 待确认。
|
||||||
|
- [ ] **P4-6**:runtime 源默认超时策略(P10-3,区分流式/非流式)— 待确认。
|
||||||
Reference in New Issue
Block a user