mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-08-13 01:33:42 +08:00
完成待办实时刷新方案评估
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
## 路由安全
|
## 路由安全
|
||||||
|
|
||||||
- 默认允许 `invoiceDetail`、`financeDetail`、`accountUserInfo` 三个业务路由。
|
- 默认允许 `invoiceDetail`、`financeDetail`、`accountUserInfo`、`AbnormalRecord` 四个业务路由。
|
||||||
- 新业务路由上线前必须追加到 `todo.route-whitelist`,不允许直接信任请求体中的路由名。
|
- 新业务路由上线前必须追加到 `todo.route-whitelist`,不允许直接信任请求体中的路由名。
|
||||||
- `route_params` 必须是 JSON 对象,只允许 `params`、`query` 两层结构,最终值只能是字符串、数字、布尔值或空值。
|
- `route_params` 必须是 JSON 对象,只允许 `params`、`query` 两层结构,最终值只能是字符串、数字、布尔值或空值。
|
||||||
- 用户端详情、已读、完成和取消接口继续使用当前登录用户 ID 作为 SQL 条件。
|
- 用户端详情、已读、完成和取消接口继续使用当前登录用户 ID 作为 SQL 条件。
|
||||||
|
|||||||
72
docs/plan/2026-07-22-todo-center-realtime-evaluation.md
Normal file
72
docs/plan/2026-07-22-todo-center-realtime-evaluation.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# 待办中心实时刷新评估
|
||||||
|
|
||||||
|
## 结论
|
||||||
|
|
||||||
|
当前继续使用首页 60 秒轮询,不新增 WebSocket 或 SSE。
|
||||||
|
|
||||||
|
现阶段没有低于 60 秒的待办送达 SLA,PRD 也将 30~60 秒轮询定义为 V1 推荐方案,将实时推送保留为实时性要求提高后的 V2 能力。现有实现能够在进入首页时立即加载、返回首页时主动刷新,并在离开页面后停止轮询,满足当前需求。
|
||||||
|
|
||||||
|
如果后续达到本文列出的升级触发条件,优先采用 SSE;WebSocket 仅在出现双向实时交互需求时考虑。实时通道只发送“待办状态已变化”事件,任务数据仍通过现有 REST 接口查询。
|
||||||
|
|
||||||
|
## 当前实现与负载
|
||||||
|
|
||||||
|
- 首页创建和重新激活时立即调用 `/system/todo/unreadCount` 与 `/system/todo/homeList?limit=3`。
|
||||||
|
- 首页激活期间每 60 秒刷新一次,并通过 `todoLoading` 避免同一页面内请求重叠。
|
||||||
|
- 页面失活或销毁时清除定时器,待办中心列表打开时自行查询。
|
||||||
|
- 每个停留在首页的活跃用户每分钟产生 2 个只读请求,理论请求速率为 `活跃首页用户数 / 30` QPS;1000 个同时停留首页的用户约为 33.3 QPS。
|
||||||
|
- 首页查询已有按接收人、状态和排序设计的索引,当前验收目标为 P95 小于 500ms;真实数据基准仍按安全与性能清单执行。
|
||||||
|
- 轮询的最坏可见延迟为 60 秒,平均约 30 秒。业务页面完成待办后已有主动刷新,不必等待下一轮轮询。
|
||||||
|
|
||||||
|
## 方案比较
|
||||||
|
|
||||||
|
| 维度 | 60 秒轮询 | SSE | WebSocket |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 当前需求匹配 | 满足 PRD 的 30~60 秒要求 | 超出当前 SLA | 超出当前 SLA |
|
||||||
|
| 通信方向 | 前端拉取 | 服务端单向通知 | 双向通信 |
|
||||||
|
| 实现成本 | 已完成 | 中 | 高 |
|
||||||
|
| 现有鉴权兼容 | 直接复用 Bearer 请求头 | 原生 `EventSource` 不能设置 Bearer 请求头,需要流式 fetch/polyfill 或鉴权改造 | 握手鉴权和令牌续期需要单独实现 |
|
||||||
|
| 多实例支持 | 无额外要求 | 需要跨实例事件分发 | 需要跨实例事件分发和连接管理 |
|
||||||
|
| 代理与运维 | 普通 HTTP | 需要关闭缓冲、配置超时和心跳 | 需要 Upgrade、超时、心跳和连接容量配置 |
|
||||||
|
| 降级 | REST 本身即主链路 | 必须回退轮询 | 必须回退轮询 |
|
||||||
|
|
||||||
|
待办只需要服务端向前端发送“数据有变化”的信号,不需要客户端通过长连接提交命令,因此若未来升级,SSE 比 WebSocket 更贴合通信模型。
|
||||||
|
|
||||||
|
## 当前基础设施缺口
|
||||||
|
|
||||||
|
- 后端没有 `spring-boot-starter-websocket`、`SseEmitter` 端点或待办连接注册表。
|
||||||
|
- `TodoTaskService` 的创建、完成、取消、过期和归档操作没有统一发布提交后事件。
|
||||||
|
- 待办由 system、pile、Quartz 等多个模块触发,需要统一事件出口,不能在各业务入口分别维护推送逻辑。
|
||||||
|
- 项目虽已配置 Redis 和 RabbitMQ,但没有面向待办用户事件的跨实例发布订阅通道;仅使用进程内连接表会在多实例部署时漏推。
|
||||||
|
- 当前后台登录是无状态 Bearer 鉴权。令牌保存在前端 Cookie 中,但服务端只读取 `Authorization` 请求头,原生 `EventSource` 无法直接复用。
|
||||||
|
- 仓库没有可验证的 Nginx/网关长连接超时、SSE 缓冲或 WebSocket Upgrade 配置。
|
||||||
|
|
||||||
|
## 升级触发条件
|
||||||
|
|
||||||
|
满足任一条件后重新评估实时推送:
|
||||||
|
|
||||||
|
1. 产品明确要求待办创建或状态变化后 10 秒内可见。
|
||||||
|
2. 待办需要在首页之外显示全局角标、桌面提醒或声音提醒。
|
||||||
|
3. 测试或生产监控表明轮询接口的 QPS、数据库负载或 P95 已超过约定容量预算,且索引和接口合并仍不足以解决。
|
||||||
|
4. 系统已经具备可复用的认证长连接、跨实例事件总线和网关长连接运维能力,接入成本明显下降。
|
||||||
|
|
||||||
|
在触发实时化之前,优先考虑低成本优化:页面不可见时暂停轮询、恢复可见时立即刷新,以及在证据表明确有必要时合并首页数量和最近待办接口。
|
||||||
|
|
||||||
|
## SSE 目标方案
|
||||||
|
|
||||||
|
1. `TodoTaskService` 在数据库事务提交后发布只包含 `assigneeUserId`、事件类型和版本号的待办变更事件,不发送标题、内容或业务参数。
|
||||||
|
2. 使用 Redis Pub/Sub 或 RabbitMQ 将事件广播到所有应用实例;每个实例只向本机对应用户的连接发送刷新信号。
|
||||||
|
3. 增加受认证保护的 `/system/todo/events` SSE 端点。前端使用支持 `Authorization` 请求头的流式 fetch/polyfill,避免把令牌放入 URL。
|
||||||
|
4. 服务端发送 20~30 秒心跳并清理断开的连接;前端自动重连,对连续事件做短时间去抖。
|
||||||
|
5. 前端收到事件后仍调用现有 `/unreadCount`、`/homeList` 或 `/list` 接口获取权威数据。
|
||||||
|
6. SSE 断开、网关不支持或事件总线异常时自动回退到 60 秒轮询;重新连接后立即全量刷新。
|
||||||
|
|
||||||
|
该方案不要求事件可靠保存。SSE 事件只是刷新提示,断线期间遗漏的事件由重连后的 REST 查询和轮询兜底。
|
||||||
|
|
||||||
|
## 实时化验收项
|
||||||
|
|
||||||
|
- 任何用户只能收到自己的刷新事件,不能从事件内容推断其他用户或运营商的任务。
|
||||||
|
- 创建、完成、取消、过期和归档均在事务提交后触发事件,回滚事务不推送。
|
||||||
|
- 单实例和多实例部署均能送达,断线重连不会造成连接泄漏。
|
||||||
|
- 令牌过期后连接关闭,重新登录后建立新连接;日志和 URL 不记录令牌。
|
||||||
|
- 长连接不可用时自动回退轮询,待办最终展示结果与数据库一致。
|
||||||
|
- 在明确实时 SLA 后,以事件提交到页面完成 REST 刷新为口径记录 P95,并在压测中验证连接数、线程数和网关超时配置。
|
||||||
Reference in New Issue
Block a user