Files
chorus/docs/06-troubleshooting.md
T

116 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- gitea-wiki-mirror:start -->
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
wiki_page: Troubleshooting
wiki_url: https://git.ilapage.cn/OPC/chorus/wiki/Troubleshooting
wiki_revision: d37761a10ea18c62e0cd0680e65d9b462d79b4f5
synchronized_at: 2026-08-20T07:01:24Z
<!-- gitea-wiki-mirror:end -->
# 故障排查
## 排查顺序
### 1. 环境与工作区
```powershell
git status --short --branch
go version
mysql --version
migrate -version
node --version
pnpm --version
```
产品构建目标为 Go 1.26.5、MySQL 8.0、Node >=22、pnpm 9.15.1。工具缺失或版本不符先记录环境问题;不要通过降低文档版本或改代码绕过。
### 2. 判断同步还是异步
| 现象 | 首查 |
|---|---|
| 提交 4xx、没有卡片 | portal 认证/CSRF/上传/幂等 |
| 卡片出现但一直 queued | worker、MySQL 版本、取任务索引 |
| running 超时 | lease owner/token/until、上游和存储超时 |
| succeeded 但无内容 | output 记录、原子文件、鉴权/缩略图 |
| 内容不符 | rendered_prompt 与模板 |
| 管理端 CRUD 不符 | migrations、导表元数据和生成差异 |
### 3. 查库但不手工改状态
```sql
SELECT id, user_id, kind, status, provider_model_id, attempt_count,
error_code, lease_owner, lease_token, lease_until,
latency_ms, created_at, finished_at
FROM generations
ORDER BY id DESC
LIMIT 10;
```
- pending 不动:worker 未启动、数据库不支持 SKIP LOCKED 或索引/事务错误。
- running 且租约过期:新 worker 应直接原子替换 token,不应先改回 pending。
- 同一任务出现互相覆盖:检查最终 UPDATE 是否匹配当前 lease_token;陈旧 worker 应影响 0 行。
- 400/401/策略拒绝却有多 Provider attempts:retryable 写反。
- 429/5xx/超时/连接错误没有故障转移(MVP-1):候选池、上限或熔断状态错误。
- failed 没有 error,或 succeeded 没有 rendered_prompt/attempts:违反持久化红线。
`lease_token` 属运行控制信息,不在对外响应或普通日志完整输出。排查记录使用任务 id 和脱敏摘要。
### 4. 用 mock 隔离上游
用 mock 构造成功、429、5xx、超时、连接错误、400、401、内容拒绝和恶意结果 URL。mock 正常而真实异常,再查 ProviderModel、网络和上游;禁止用真实额度循环试错。真实连通性只通过受审计且有冷却的按钮触发。
### 5. SSRF 与网络
依次检查:
1. base_url scheme/host/port;
2. DNS 的每个 IPv4/IPv6 结果;
3. DialContext 是否拒绝私网、回环、链路本地、组播和未指定地址;
4. 每次 redirect 是否重新校验并限制次数;
5. 环境代理是否绕开安全 Dial;
6. 上游返回的结果 URL 是否复用相同客户端。
拦截私网是正确行为,不能为联调关闭。需要访问内部 mock 时把 mock 与测试进程放在专用测试网络,并使用测试专用注入点,不在生产配置放行私网。
### 6. 文件和权限
- 检查临时文件与最终目录是否同文件系统,rename 是否原子;
- 检查失败/陈旧 worker 是否只清理自己创建的临时文件;
- 检查数据库 output 与实际文件一致;
- 403 多为用户归属校验,404 多为记录/文件不一致;
- 不得临时把存储目录改成无鉴权静态目录。
### 7. go-admin 与代码生成
| 现象 | 处理 |
|---|---|
| 生成器看不到表 | 先确认隔离库已执行 migrations,再导入元数据 |
| “迁移脚本”没有建表 | 它主要生成菜单/API 配置,不是业务 DDL |
| 生成后菜单立刻变化 | 可能调用了副作用 `/gen/todb`;停止并恢复隔离库 |
| 生成文件落错目录 | 检查固定提交的 generator 配置,人工审查差异 |
| 生产能访问 dev-tools | 高风险发布阻断;下线路由而非只隐藏菜单 |
| 启动时表结构变化 | 检查是否误接 AutoMigrate,立即停止部署 |
### 8. 文档与 Harness
| 症状 | 处理 |
|---|---|
| strict 缺章节 | 恢复精确标题 |
| sync --check 不一致 | 先判断 Wiki 是否更新;不要直接改镜像 |
| sync 因本地镜像改动停止 | 保留用户改动,查清来源后处理 |
| Wiki 无 revision | 停止同步,从失败页面继续 |
| API 401 | 从安全环境重新加载有效 PAT,不打印令牌 |
| MCP 连接失败 | 在工单记录原因后回退 API |
### 9. 仍未定位
在工单记录最小复现、任务 id、脱敏 attempts/error、租约时间线、相关日志和已排除项。不得粘贴 API Key、Cookie、真实 prompt、用户文件或生产数据。
## 必须停止的情况
- 需要修改 retryable、SSRF、密钥、租约、迁移、身份或权限;
- 需要手工改共享/生产库、回退状态、删除数据或文件;
- 想通过 AutoMigrate、关闭 SSRF、公开存储或暴露 dev-tools 临时绕过;
- 需要反复真实上游调用;
- 日志疑似泄密或包含个人/生产数据;
- 同一阻塞尝试两次仍不能确认根因。