This commit is contained in:
lik
2026-09-01 21:50:07 +08:00
parent b7def15527
commit d9e692b2c0
3 changed files with 74 additions and 2 deletions
+72
View File
@@ -0,0 +1,72 @@
# ws_health 后端架构与优化方案
> 更新时间:2026-08-30
## 一、当前结构
```
d:\work\ws_health
├── api/ # 所有后台服务,每类服务一个目录,各自独立部署
│ ├── health/ # 陪诊业务服务(订单/健康档案/资源/WS AI 聊天)
│ │ ├── HTTP :9004 # RESTkoa
│ │ └── WS :9005 # WebSocketAI 聊天,Agent 按 userId 缓存)
│ └── user/ # 用户服务(注册/登录/token 鉴权/微信登录)
│ └── HTTP :9010
├── ui/ # 小程序端
│ ├── wxapp_escort/ # C 端
│ └── wxapp_escort_admin/ # 管理端
└── doc/
```
- **网关**:nginx 按路径转发(`/health → 9004``/user → 9010``/ws → 9005`),参见 `api/health/nginx_site.txt`
- **数据库**:共用同一 MongoDB 实例,**按服务分库**user 用 `eiot_user` 库,health 用自己的库),各自独立连接配置
- **认证体系**token 单点在 user 服务(DB 存 sha256 哈希);health 服务通过 HTTP 实时调用 `/user/userInfo` 校验
- **技术栈**Node/Koa/MongooseAI 聊天基于 LangChain AgentDeepSeek/Tavily/百度地图)
## 二、架构结论
服务按目录拆分 + nginx 路由 + 分库的方案,**对中等 HTTP 流量(日请求百万级内、团队 3~10 人)完全够用**,属于标准的模块化单体 → 轻量微服务路径。
分库优于表前缀:边界清晰、索引不冲突、无历史包袱;量大时可平滑迁移到独立实例。
## 三、已完成的安全加固(2026-08-30 code review 后修复)
### health 服务
- 补齐 `findRecordsByAttendant`(原接口必然 500
- escort-record / health-profile 全部路由挂载鉴权中间件(token → user 服务校验)
- `GET /escort-record/my` 强制按登录用户过滤(修 IDOR);新增 `GET /escort-record` 供管理端查全部
- create/update 白名单过滤(兼容点号路径);连接日志脱敏;WS 聊天强制 token 校验、断连保护
### user 服务
- 修复两个账号接管漏洞:匿名 `userInfo(userId)` 不再返回 `security.token``wxSignin` 不再信任客户端直传手机号绑定/覆盖已有账号(新增 `phoneCode` 服务端验证)
- `auth()` 中间件正式挂载;token 改 sha256 哈希入库(兼容旧明文自动迁移)
- 登录失败 ≥10 次自动锁定;微信 access_token 进程内缓存(防配额耗尽)
- `userList` 补 total、pageSize 上限 200
### 遗留手动事项
1. **轮换凭证**MongoDB 密码、微信 AppSecretuser 服务 conf.json)、`.env` 内 3 个 API key 均已入 git 历史;`.gitignore` 已补,需 `git rm --cached conf.json .env` 并更换凭证
2. 锁定账户解锁目前需手动改库(`status.account: "normal"` + 重置 `failedLoginAttempts`),后续可加管理端解锁接口
## 四、优化方案(按优先级)
### 1. ✅ health 鉴权调用加缓存(2026-08-30 已完成)
- 新增 `api/health/utils/user_service.js`token→user 进程内缓存,**TTL 5 分钟**
- LRU 上限 2000 条,防止无限增长
- 无效 token 负缓存 60 秒,防止伪造 token 打爆 user 服务
- 网络异常不缓存,直接走降级路径
- `requireAuth`REST)与 WS 聊天的 `getUserInfo` 统一走该缓存,每请求不再实时调用 user 服务
- 已知代价:**登出/账户锁定在 health 侧最多延迟 5 分钟生效**(user 服务自身接口即时生效)
- 中期规划:user 服务签发 JWT(短 access 无状态 + refresh 可撤销,Redis 黑名单兜底),之后新模块接入鉴权零成本;在引入"每请求查 Redis"的方案时,直接用不透明 token 存 Redis 即可,无需 JWT
### 2. 内存态组件在水平扩容前外移 Redis
以下均为单进程内存态,单实例部署没问题;nginx 挂多实例后失效:
- user 服务限流(IP+路径维度)
- user 服务微信 access_token 缓存
- health 服务 WS Agent 缓存(现为 LRU 上限 100
### 3. 配置统一
两个服务各一份 conf.json,Mongo 连接信息重复、凭证轮换需改多处。建议统一到服务器级 `.env`,服务内只读环境变量;`.env`/`conf.json` 均已加入 .gitignore。
### 边界提醒
- **跨服务事务**:目前无需求;将来"订单+支付+用户"强一致场景用 API 补偿/异步消息,不上分布式事务
- **表前缀方案已放弃**:同库前缀隔离长期会互相踩字段,分库无此问题