hi-server/.trae/documents/排查并修复解绑设备接口产生 502 的问题.md
shanshanzhong 6b65ffb728
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m4s
fix(user): 修复解绑设备接口的502错误和安全断言问题
修复不安全类型断言可能导致panic的问题,将Redis清理移出事务并添加超时控制
增加代理层超时配置和详细日志,提升接口稳定性
2025-12-01 21:24:11 -08:00

33 lines
3.3 KiB
Markdown
Raw Permalink 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.

## 结论与定位
- 解绑接口路径:`/v1/public/user/unbind_device`,路由注册于 `internal/handler/routes.go:836-838`,处理器在 `internal/handler/public/user/unbindDeviceHandler.go:11-25`
- 业务逻辑:`internal/logic/public/user/unbindDeviceLogic.go:36-141`,进行设备所属用户迁移、认证记录更新、可能删除旧用户以及 Redis 缓存清理。
- 返回封装:所有接口错误均走 JSON 200 包装,见 `pkg/result/httpResult.go:12-33`,因此应用层不会主动返回 502。
- Nginx 反向代理API 代理到 `127.0.0.1:8080`,见 `etc/nginx.conf:233-260`;未设置显式的 `proxy_read_timeout` 等超时参数502 多发生在上游超时或连接被复位。
## 高概率问题点
- 非安全类型断言导致潜在 panic`internal/logic/public/user/unbindDeviceLogic.go:38` 直接 `.(*user.User)` 断言若上下文未注入用户Token 缺失/失效、链路异常),将发生 panic。其他多数逻辑使用安全断言并兜底`internal/logic/public/user/unbindOAuthLogic.go:31-36`)。
- 同类不安全用法还出现在 `internal/logic/public/user/getDeviceListLogic.go:31-33`(你反馈其他接口正常,但它也可能受影响,建议同修)。
- 事务中混入外部 IO在 DB 事务闭包内进行 Redis 删除(`internal/logic/public/user/unbindDeviceLogic.go:125-131`),若外部 IO 波动叠加数据库锁等待,整体耗时可能逼近或超过代理默认超时,引发 502。
## 修复方案
- 将所有 `CtxKeyUser` 获取统一改为安全断言:
- 失败时返回 `InvalidAccess` 业务错误而非 panic参考 `unbindOAuth` 的处理方式;修改位置:`internal/logic/public/user/unbindDeviceLogic.go:36-43``internal/logic/public/user/getDeviceListLogic.go:31-33`
- 将 Redis 缓存清理移出事务闭包,并添加超时控制:
- 事务仅做数据库一致性操作;在事务成功后再进行缓存删除,失败则不删;为 Redis 操作设置短超时,避免阻塞主流程。
- 增强可观测性:
- 在解绑入口和事务前后增加结构化日志,包含 `device_id``user_id`、事务耗时、Redis 耗时、错误栈;方便精确定位是否存在偶发长耗时。
- 代理层稳健性:
- 在 Nginx 针对 API 站点增加 `proxy_connect_timeout 10s; proxy_send_timeout 60s; proxy_read_timeout 60s;`,并开启 `proxy_next_upstream timeout`;避免上游短抖动即直接 502。
## 验证计划
- 单元测试:构造上下文缺失用户的请求,确认不再 panic返回业务错误码而非 502。
- 事务耗时压测:模拟高并发解绑,观察事务与 Redis 操作耗时分布,确认在代理超时阈值内。
- 端到端验证:
- 使用有效与无效 Token、不同设备 ID 连续调用解绑,确认响应始终为 200 JSON 包装(或业务错误),不出现 502。
- 对比 Nginx 错误日志,验证 502 消失。
## 变更范围
- 代码改动:`internal/logic/public/user/unbindDeviceLogic.go``internal/logic/public/user/getDeviceListLogic.go` 增加安全断言与错误返回;调整 Redis 清理至事务外并加超时;补充必要日志。
- 配置更新:`etc/nginx.conf` 的 API server 段增加代理超时与上游重试策略。
请确认以上方案,我将按该方案实施、编写必要函数注释并补充测试,完成后提供验证结果与影响评估。