v3.1 + 批次0: 智能回复重构基线 - ApprovalMatcher + 关键词降级 + 文档速修 + v4.0任务书面化
This commit is contained in:
+184
-5
@@ -1,9 +1,16 @@
|
||||
# 00 · 标准故障排查手册
|
||||
|
||||
> **版本**: v1.4 | **日期**: 2026-07-10 | **维护人**: 宋献 / 助理
|
||||
> **版本**: v1.9 | **日期**: 2026-07-16 | **维护人**: 宋献 / 助理
|
||||
> **定位**: 所有故障排查前**首先查看本手册**。
|
||||
> **最新**: 方案 C(卷挂载)已上线,§1.4 更新为 volume 挂载验证 + CASE-20260710-02 标注根因已消除 + 错误码速查更新
|
||||
> **最新**: 新增 CASE-20260716-01(员工端 /h5/ 404 — nginx 反向代理配置错误)
|
||||
|
||||
| v1.6 | 2026-07-14 | 新增 CASE-20260714-01(前端 bind mount 未生效导致 403)+ 错误码速查更新 |
|
||||
| v1.7 | 2026-07-14 | 新增 CASE-20260714-02(员工端 /h5/ 404 — nginx 配置错误)|
|
||||
| v1.9 | 2026-07-16 | 新增 CASE-20260716-01(员工端 /h5/ 404 — nginx 反向代理配置错误)|
|
||||
| v1.8 | 2026-07-15 | 新增 CASE-20260715-01(员工端审批模板ID不正确 — 企微审批模板失效)|
|
||||
| v1.7 | 2026-07-14 | 新增 CASE-20260714-01(前端 bind mount 未生效导致 403)+ 错误码速查更新 |
|
||||
| v1.6 | 2026-07-14 | 新增 CASE-20260714-02(员工端 /h5/ 404 — nginx 配置错误)|
|
||||
| v1.5 | 2026-07-13 | 新增 CASE-20260713-01(nginx rewrite 不全导致 502)+ CASE-20260713-02(@require_role 装饰器参数缺失) |
|
||||
| v1.4 | 2026-07-10 | 方案 C 上线:§1.4 改为 volume 挂载验证 + 错误码速查更新 + CASE-20260710-02 根因已消除标注 |
|
||||
> **前置阅读**: [运维手册(部署/回滚/备份/应急)](../01-项目总览/01-智能IT服务系统运维手册-20260704.md) · [SOP-04 应急响应](../10-项目管理/SOPs-标准流程/SOP-04-应急响应.md)
|
||||
|
||||
@@ -136,16 +143,41 @@ python jms_ops.py exec \
|
||||
|
||||
> ⚠️ 代码更新后 `docker compose restart` 即可(15-30 秒)。仅当 `requirements.txt` 有变化时才需要 `docker compose build`。
|
||||
|
||||
#### 前端部署检查清单(bind mount 模式)
|
||||
|
||||
**触发条件**:任何前端文件更新(`frontend-*/dist/` 目录变更)。
|
||||
|
||||
```bash
|
||||
# 1. 验证宿主机源目录有文件
|
||||
ls -la /opt/wecom-it-desk/frontend-agent/dist/ # 坐席端
|
||||
ls -la /opt/wecom-it-desk/frontend-h5/dist/ # H5 端
|
||||
|
||||
# 2. 验证容器内挂载成功(关键!)
|
||||
docker exec wecom_it_nginx ls /usr/share/nginx/html/itagent/ # 坐席端
|
||||
docker exec wecom_it_nginx ls /usr/share/nginx/html/h5/ # H5 端
|
||||
|
||||
# 3. 如容器内为空,强制重建 nginx 容器
|
||||
cd /opt/wecom-it-desk
|
||||
docker compose stop nginx
|
||||
docker compose rm -f nginx
|
||||
docker compose up -d nginx
|
||||
|
||||
# 4. 验证外部可访问
|
||||
curl -sI https://itsupport.servyou.com.cn/itagent/ | head -3
|
||||
```
|
||||
|
||||
> ⚠️ **bind mount 有时不生效**:即使 docker-compose.yml 配置正确,挂载也可能失效。前端部署后务必验证容器内文件存在(步骤2),否则会 403。
|
||||
|
||||
---
|
||||
|
||||
## 2 常见错误码速查(E5xx)
|
||||
|
||||
| 错误码 | 含义 | 首选排查 |
|
||||
|--------|------|---------|
|
||||
| **E500** | 后端未捕获异常 / 缺列 / 缺依赖 | `docker compose logs backend --tail=200 \| grep -i error`;查数据库缺列 / 缺 Python 依赖 |
|
||||
| **E502** | nginx 连不到后端 | 后端容器 `unhealthy`?`docker logs wecom_it_backend`;是否缺 `PYTHONPATH=/app` |
|
||||
| **E500** | 后端未捕获异常 / 缺列 / 缺依赖 / 装饰器参数不匹配 | `docker compose logs backend --tail=200 \| grep -i error`;查数据库缺列 / 缺 Python 依赖;检查 `@require_role` 等装饰器是否与函数签名不匹配(见 CASE-20260713-02) |
|
||||
| **E502** | nginx 连不到后端 / 路由不匹配 | 后端容器 `unhealthy`?`docker logs wecom_it_backend`;检查 nginx rewrite 是否正确剥离 `/api/` 前缀(见 CASE-20260713-01) |
|
||||
| **E503** | 服务过载 / 维护 | `docker stats`;`docker inspect ... Health` |
|
||||
| **E403** | IP 白名单 / 无权限 | `grep allow /opt/wecom-it-desk/nginx/nginx.conf`;admin 角色不足 |
|
||||
| **E403** | IP 白名单 / 无权限 / 前端挂载未生效 | `grep allow /opt/wecom-it-desk/nginx/nginx.conf`;admin 角色不足;前端部署后检查 `docker exec wecom_it_nginx ls <挂载路径>` 确认容器内文件存在(见 CASE-20260714-01) |
|
||||
| **E422** | 请求体校验失败(Pydantic)| 确认必填字段齐全(如登录需 `user_id`+`name`)|
|
||||
| **网络失败 / 连接挂起** | 依赖不可达(最常见 Redis 配置错)| 见 §1.2 / CASE-20260707-01 |
|
||||
| **页面 200 但 JS 不执行** | CSP 头 `script-src` 缺 `'unsafe-inline'`,内联 `<script>` 被浏览器静默拦截 | `curl -ksI <URL> \| grep content-security`;检查 `script-src` 是否含 `'unsafe-inline'`(见 CASE-20260710-01)|
|
||||
@@ -201,6 +233,153 @@ docker logs wecom_it_backend | grep -i websocket
|
||||
|
||||
## 4 案例库(倒序,编号 CASE-YYYYMMDD-序号)
|
||||
|
||||
### CASE-20260716-01 · 员工端 /h5/ 404 — nginx 反向代理配置错误 ⭐⭐
|
||||
- **现象**:企微工作台 → IT智能服务 → `https://itsupport.servyou.com.cn/h5/` 返回 `{"detail":"Not Found"}`(FastAPI 404)
|
||||
- **根因**:nginx 配置中 `/h5/` 被错误配置为**反向代理**到后端 API(`proxy_pass http://backend_api/`),而不是静态文件服务。后端没有 `/h5/` 路由,返回 404
|
||||
- **诊断**:
|
||||
1. `docker logs wecom_it_nginx | grep /h5/` → 显示后端返回 404
|
||||
2. `docker exec wecom_it_nginx cat /etc/nginx/nginx.conf | grep -A5 'location /h5/'` → 发现 `proxy_pass http://backend_api/`
|
||||
3. 确认 H5 静态文件已正确挂载:`docker exec wecom_it_nginx ls /usr/share/nginx/html/h5/`
|
||||
- **修复**:
|
||||
1. **docker-compose.yml**:新增 H5 挂载到 `/h5/`
|
||||
```
|
||||
- ./frontend-h5/dist:/usr/share/nginx/html/h5:ro
|
||||
```
|
||||
2. **nginx/nginx.conf**:将 `/h5/` 从反向代理改为静态文件服务
|
||||
```
|
||||
location /h5/ {
|
||||
alias /usr/share/nginx/html/h5/;
|
||||
index index.html;
|
||||
try_files $uri /h5/index.html;
|
||||
}
|
||||
```
|
||||
3. **部署**:上传配置后重建 nginx 容器
|
||||
```
|
||||
cd /opt/wecom-it-desk
|
||||
docker compose stop nginx && docker compose rm -f nginx && docker compose up -d nginx
|
||||
```
|
||||
- **验证**:
|
||||
- 容器内 `curl -sI http://localhost/h5/` → HTTP 200
|
||||
- 浏览器访问 `https://itsupport.servyou.com.cn/h5/` → 正常显示 H5 页面
|
||||
- **⚠️ 教训**:
|
||||
1. **H5 前端是静态文件应用**,nginx 应配置 `alias` 或 `root` 提供静态文件,而不是 `proxy_pass` 到后端
|
||||
2. **这是第二次出现同类问题**:上次 CASE-20260714-02 修复后,今天再次出现,可能是上次修复未同步到服务器或配置被覆盖
|
||||
3. **bind mount 有时不生效**:即使 docker-compose.yml 配置正确,挂载也可能失效。前端部署后务必验证容器内文件存在
|
||||
4. **建议**:在 nginx 配置中添加注释说明 `/h5/` 是静态文件服务,避免未来误改
|
||||
|
||||
### CASE-20260715-01 · 员工端审批"获取审批流程失败,审批模板ID不正确" ⭐⭐
|
||||
- **现象**:员工端H5点击"IT资产升级"、"设备申请"、"商业软件申请"等审批卡片时,提示"获取审批流程失败,审批模板ID不正确"。
|
||||
- **根因**(两层代码都需要修复):
|
||||
1. **前端**:`RecommendCard.vue` 中 `APPROVAL_URL_MAP` 的 `asset_upgrade` 映射到企微审批模板 `Bs7ucTGs...`(已失效),`商业软件申请` 映射到企微审批模板 `3TmACf8D...`(也已失效),第298-299行硬编码 fallback 跳转到失效的企微审批URL
|
||||
2. **后端**:`backend/app/api/approval.py` 中 `APPROVAL_TEMPLATES` 字典的 `asset_upgrade` 和 `software_service` 同样映射到失效的企微审批模板(第81行和第115行)
|
||||
- **诊断**:
|
||||
1. 浏览器F12查看网络请求,确认调用的是企微审批模板URL
|
||||
2. 检查前端 `RecommendCard.vue` 和后端 `approval.py` 中的URL映射
|
||||
3. 对比 `ApprovalCardModal.vue` 中的正确映射(已改用ITSM)
|
||||
- **修复**:
|
||||
1. **前端**:`frontend-h5/src/components/assistant/RecommendCard.vue`
|
||||
- 将 `asset_upgrade` 改为ITSM工单系统URL
|
||||
- 将 `商业软件申请` 改为ITSM工单系统URL
|
||||
- 修改 `handleActionClick()` 的fallback逻辑,移除硬编码的失效URL
|
||||
- 构建:`npm run build` → 部署到 `/opt/wecom-it-desk/frontend-h5/dist/`
|
||||
2. **后端**:`backend/app/api/approval.py`
|
||||
- 将 `asset_upgrade` 的 `url` 改为ITSM工单系统URL,`location` 改为"运维平台"
|
||||
- 将 `software_service` 的 `url` 改为ITSM工单系统URL,`location` 改为"运维平台"
|
||||
- 上传到服务器:`/opt/wecom-it-desk/app/api/approval.py`
|
||||
- 重启后端:`docker compose restart backend`
|
||||
3. 部署:`docker exec wecom_it_nginx nginx -s reload`
|
||||
- **验证**:浏览器访问H5,点击审批卡片,跳转到ITSM工单系统而非企微审批(已失效模板)
|
||||
- **⚠️ 教训**:
|
||||
1. **审批入口有两层**:左侧"企微-审批"入口数据来自后端API `/approval/links`,AI推荐卡片来自前端代码,两者都需要修复
|
||||
2. **企微审批模板会失效**:审批模板在企微后台可能被删除或变更,前端不应硬编码模板ID
|
||||
3. **ITSM是更稳定的方案**:ITSM工单系统URL更稳定,不受企微审批模板变更影响
|
||||
4. **推荐做法**:所有审批类型统一使用ITSM工单系统,前后端都要同步修改
|
||||
|
||||
### CASE-20260714-01 · 坐席端 403 错误 — 前端 bind mount 未生效 ⭐⭐
|
||||
- **现象**:坐席端 `/itagent/` 返回 403 Forbidden,浏览器控制台显示 `Failed to load resource: the server responded with a status of 403`。
|
||||
- **根因**:前端文件虽然上传到服务器 `/opt/wecom-it-desk/frontend-agent/dist/`,但 nginx 容器的 bind mount 没有正确工作,容器内 `/usr/share/nginx/html/itagent/` 目录为空。
|
||||
- **诊断**:
|
||||
1. `docker exec wecom_it_nginx ls -la /usr/share/nginx/html/itagent/` → 容器内目录为空
|
||||
2. `docker inspect wecom_it_nginx | grep itagent` → 挂载配置存在且正确(`Source: /opt/wecom-it-desk/frontend-agent/dist`)
|
||||
3. `ls -la /opt/wecom-it-desk/frontend-agent/dist/` → 宿主机源目录有文件
|
||||
4. nginx 日志显示 `directory index of "/usr/share/nginx/html/itagent/" is forbidden`
|
||||
- **修复**:
|
||||
```bash
|
||||
# 重建 nginx 容器让 bind mount 生效
|
||||
cd /opt/wecom-it-desk
|
||||
docker compose stop nginx
|
||||
docker compose rm -f nginx
|
||||
docker compose up -d nginx
|
||||
```
|
||||
- **验证**:`docker exec wecom_it_nginx ls -la /usr/share/nginx/html/itagent/` → 容器内文件存在;外部访问 `/itagent/` → HTTP 200
|
||||
- **⚠️ 教训**:
|
||||
1. **bind mount 有时不生效**:即使 docker-compose.yml 配置正确,挂载也可能失效。重建容器是常用解决方法。
|
||||
2. **容器内目录为空但宿主机有文件 ≠ 挂载成功**:必须进入容器内验证,不能只看宿主机。
|
||||
3. **前端部署后务必验证容器内文件**:用 `docker exec <容器> ls <挂载路径>` 确认。
|
||||
4. **此问题可能复发**:任何前端部署(dist 目录更新)后,建议重建 nginx 容器确保挂载生效。
|
||||
|
||||
- **复发记录**:
|
||||
- 2026-07-16:再次发生,返回 500(rewrite 循环 `internal redirection cycle while internally redirecting to "/itage"`),重建 nginx 容器修复
|
||||
|
||||
### CASE-20260714-02 · 员工端 /h5/ 404 — nginx 配置错误 ⭐⭐
|
||||
- **现象**:员工端打开报错 `Failed to load resource: the server responded with a status of 404 (Not Found)`。
|
||||
- **根因**:nginx 配置中 `/h5/` 被错误配置为**反向代理**到后端(`proxy_pass http://backend_api/`),而不是静态文件服务。后端没有 `/h5/` 路由,导致返回 404。
|
||||
- **诊断**:
|
||||
1. `docker logs wecom_it_nginx | grep /h5/` → 显示 `GET /h5/ HTTP/1.1" 404`
|
||||
2. `docker exec wecom_it_nginx cat /etc/nginx/nginx.conf | grep -A10 'location /h5/'` → 发现 `proxy_pass http://backend_api/`
|
||||
3. 确认静态文件已正确挂载:`docker exec wecom_it_nginx ls /usr/share/nginx/html/h5/`
|
||||
- **修复**:修改 `nginx/nginx.conf`,将 `/h5/` 从反向代理改为静态文件服务:
|
||||
```
|
||||
location /h5/ {
|
||||
alias /usr/share/nginx/html/h5/;
|
||||
index index.html;
|
||||
try_files $uri /h5/index.html;
|
||||
}
|
||||
```
|
||||
部署:`docker compose restart nginx`
|
||||
- **验证**:浏览器访问 `https://itsupport.servyou.com.cn/h5/` → HTTP 200,显示"仅限企业微信访问"页面
|
||||
- **⚠️ 教训**:
|
||||
1. **H5 前端是静态文件应用**,nginx 应配置 `alias` 或 `root` 提供静态文件,而不是 `proxy_pass` 到后端。
|
||||
2. **本地 nginx.conf 与服务器不同步**:发现问题后,检查本地配置是否已修复(本次修复已同步到本地 `nginx/nginx.conf`)。
|
||||
3. **常见混淆**:`/itdesk/` 和 `/h5/` 都指向 H5 应用,但只有 `/itdesk/` 是在企微工作台中配置的入口。两者都应配置为静态文件服务。
|
||||
|
||||
### CASE-20260713-02 · 坐席端 502 错误 — @require_role 装饰器参数缺失 ⭐⭐
|
||||
- **现象**:坐席端 `/itagent/` 全部 API 返回 502,后端日志显示 `TypeError: list_agents() got an unexpected keyword argument 'current_user'`。
|
||||
- **根因**:`@require_role` 装饰器在调用被装饰函数时强制传递 `current_user` 参数,但部分使用该装饰器的函数未声明此参数。
|
||||
- **诊断**:`docker logs wecom_it_backend | grep -i error` 查看具体错误;定位缺少参数的函数。
|
||||
- **修复**:
|
||||
1. `backend/app/api/agents.py` 第 425 行:添加 `current_user: UserInfo = Depends(get_current_user)`
|
||||
2. `backend/app/api/otp.py` 第 348 行和第 389 行:同样添加 `current_user` 参数
|
||||
3. 部署:`docker compose restart backend`
|
||||
- **验证**:后端 `/health` → 200 OK;`/agents` → 200 OK
|
||||
- **⚠️ 教训**:
|
||||
1. **所有使用 `@require_role` 装饰器的函数都必须声明 `current_user` 参数**,装饰器会自动注入此参数。
|
||||
2. 排查 502 错误时,先检查后端日志中的 `TypeError` 错误,可能是装饰器参数不匹配。
|
||||
3. 建议在代码中添加类型注解和 lint 规则,提前发现此类问题。
|
||||
|
||||
### CASE-20260713-01 · 坐席端 502 错误 — nginx rewrite 规则不完整 ⭐⭐
|
||||
- **现象**:部分 API(如 `/api/auth/qrcode`)返回 502,但 `/api/agents` 返回 200。
|
||||
- **根因**:nginx 配置只对 `/api/admin/` 路径做 rewrite 剥离前缀,其他路径(如 `/api/auth/`)未处理,导致后端收到 `/api/auth/qrcode` 而非 `/auth/qrcode`,路由不匹配返回 404。
|
||||
- **诊断**:
|
||||
1. `docker logs wecom_it_nginx | grep 502` 查看哪些路径返回 502
|
||||
2. `docker exec wecom_it_backend curl http://localhost:8000/auth/qrcode` 直接测试后端(绕过 nginx)
|
||||
3. 检查 nginx 配置 `location /api/` 是否正确 rewrite
|
||||
- **修复**:修改 `nginx/nginx.conf`,对所有 `/api/` 路径统一做 rewrite:
|
||||
```
|
||||
location /api/ {
|
||||
# 剥离 /api/ 前缀,使后端收到 /auth/... 而非 /api/auth/...
|
||||
rewrite ^/api/(.*)$ /$1 break;
|
||||
proxy_pass http://backend_api;
|
||||
...
|
||||
}
|
||||
```
|
||||
部署:`docker restart wecom_it_nginx`
|
||||
- **验证**:外部访问 `/api/auth/qrcode` → 200 OK
|
||||
- **⚠️ 教训**:
|
||||
1. **nginx rewrite 规则必须覆盖所有需要剥离前缀的路径**,不能只处理特定路径(如 `/api/admin/`)。
|
||||
2. 判定矩阵更新:`/xxx/ 200 但 /api/... 404` → 检查 nginx 是否正确 rewrite。
|
||||
3. 部署新功能后,务必用真实浏览器测试所有关键路径,不能只测"看起来正常"的端点。
|
||||
|
||||
### CASE-20260710-02 · 坐席端/管理端登录"获取二维码失败"(Docker 镜像缺文件)⭐⭐
|
||||
- **现象**:坐席端和管理端登录均报"获取二维码失败",浏览器控制台显示 `WebSocket connection failed` + `/api/auth/qrcode` 返回 404。
|
||||
- **误判历程**:
|
||||
|
||||
Reference in New Issue
Block a user