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

4.5 KiB
Raw Blame History

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.tokenwxSignin 不再信任客户端直传手机号绑定/覆盖已有账号(新增 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.jstoken→user 进程内缓存,TTL 5 分钟
    • LRU 上限 2000 条,防止无限增长
    • 无效 token 负缓存 60 秒,防止伪造 token 打爆 user 服务
    • 网络异常不缓存,直接走降级路径
  • requireAuthREST)与 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 补偿/异步消息,不上分布式事务
  • 表前缀方案已放弃:同库前缀隔离长期会互相踩字段,分库无此问题