Files
ws_health/doc/backend-architecture.md
T
2026-09-01 21:50:07 +08:00

73 lines
4.5 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.
# 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 补偿/异步消息,不上分布式事务
- **表前缀方案已放弃**:同库前缀隔离长期会互相踩字段,分库无此问题