mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-08-12 17:23:50 +08:00
5.6 KiB
5.6 KiB
待办中心实时刷新评估
结论
当前继续使用首页 60 秒轮询,不新增 WebSocket 或 SSE。
现阶段没有低于 60 秒的待办送达 SLA,PRD 也将 30~60 秒轮询定义为 V1 推荐方案,将实时推送保留为实时性要求提高后的 V2 能力。现有实现能够在进入首页时立即加载、返回首页时主动刷新,并在离开页面后停止轮询,满足当前需求。
如果后续达到本文列出的升级触发条件,优先采用 SSE;WebSocket 仅在出现双向实时交互需求时考虑。实时通道只发送“待办状态已变化”事件,任务数据仍通过现有 REST 接口查询。
当前实现与负载
- 首页创建和重新激活时立即调用
/system/todo/unreadCount与/system/todo/homeList?limit=3。 - 首页激活期间每 60 秒刷新一次,并通过
todoLoading避免同一页面内请求重叠。 - 页面失活或销毁时清除定时器,待办中心列表打开时自行查询。
- 每个停留在首页的活跃用户每分钟产生 2 个只读请求,理论请求速率为
活跃首页用户数 / 30QPS;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 配置。
升级触发条件
满足任一条件后重新评估实时推送:
- 产品明确要求待办创建或状态变化后 10 秒内可见。
- 待办需要在首页之外显示全局角标、桌面提醒或声音提醒。
- 测试或生产监控表明轮询接口的 QPS、数据库负载或 P95 已超过约定容量预算,且索引和接口合并仍不足以解决。
- 系统已经具备可复用的认证长连接、跨实例事件总线和网关长连接运维能力,接入成本明显下降。
在触发实时化之前,优先考虑低成本优化:页面不可见时暂停轮询、恢复可见时立即刷新,以及在证据表明确有必要时合并首页数量和最近待办接口。
SSE 目标方案
TodoTaskService在数据库事务提交后发布只包含assigneeUserId、事件类型和版本号的待办变更事件,不发送标题、内容或业务参数。- 使用 Redis Pub/Sub 或 RabbitMQ 将事件广播到所有应用实例;每个实例只向本机对应用户的连接发送刷新信号。
- 增加受认证保护的
/system/todo/eventsSSE 端点。前端使用支持Authorization请求头的流式 fetch/polyfill,避免把令牌放入 URL。 - 服务端发送 20~30 秒心跳并清理断开的连接;前端自动重连,对连续事件做短时间去抖。
- 前端收到事件后仍调用现有
/unreadCount、/homeList或/list接口获取权威数据。 - SSE 断开、网关不支持或事件总线异常时自动回退到 60 秒轮询;重新连接后立即全量刷新。
该方案不要求事件可靠保存。SSE 事件只是刷新提示,断线期间遗漏的事件由重连后的 REST 查询和轮询兜底。
实时化验收项
- 任何用户只能收到自己的刷新事件,不能从事件内容推断其他用户或运营商的任务。
- 创建、完成、取消、过期和归档均在事务提交后触发事件,回滚事务不推送。
- 单实例和多实例部署均能送达,断线重连不会造成连接泄漏。
- 令牌过期后连接关闭,重新登录后建立新连接;日志和 URL 不记录令牌。
- 长连接不可用时自动回退轮询,待办最终展示结果与数据库一致。
- 在明确实时 SLA 后,以事件提交到页面完成 REST 刷新为口径记录 P95,并在压测中验证连接数、线程数和网关超时配置。