123 lines
5.6 KiB
Markdown
123 lines
5.6 KiB
Markdown
<!-- gitea-wiki-mirror:start -->
|
||
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
|
||
wiki_page: Troubleshooting
|
||
wiki_url: https://git.ilapage.cn/OPC/chorus/wiki/Troubleshooting
|
||
wiki_revision: 604293744eb29bd1ec4ac03d939e0305336e1d48
|
||
synchronized_at: 2026-08-22T03:08:35Z
|
||
<!-- 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 临时绕过;
|
||
- 需要反复真实上游调用;
|
||
- 日志疑似泄密或包含个人/生产数据;
|
||
- 同一阻塞尝试两次仍不能确认根因。
|
||
|
||
## 管理端登录后无菜单或 Chorus API 返回 403
|
||
|
||
1. 确认数据库已执行到最新 migration,`sys_casbin_rule` 中存在 `chorus_operator` 对应 `/api/v1/chorus/*` 权限。
|
||
2. 当前实现只读取 `sys_casbin_rule` 并关闭 Casbin adapter AutoMigrate;若旧进程曾生成空的 `casbin_rule`,它不是权限事实来源,不要向其中补数据。
|
||
3. 确认 bootstrap 账号绑定启用的 `chorus_operator`,重新登录取得新 JWT,再检查 `/api/v1/menurole`。
|
||
4. `settings.yml` 出现 `Unknown database` 时先创建空库并执行版本化 migration;出现 `Access denied` 时修正本地凭据,不运行 AutoMigrate 绕过。
|