网络延迟本身不直接导致事件堆积,真正原因是断连重连、服务端无断点续传、前端无背压控制三者叠加;sse需服务端支持last-event-id续传、前端节流渲染、代理层禁用缓冲、客户端指数退避重连。

网络延迟本身不会直接导致事件堆积,真正引发前端卡死或消息积压的,是断连重连 + 服务端无断点续传 + 前端无背压控制三者叠加的结果。SSE 的设计本意是流式、有序、轻量推送,但一旦中间环节失配,10万条消息瞬间涌进页面就不是夸张——而是真实发生过的 P0 级事故。
服务端必须支持 Last-Event-ID 断点续传
这是防堆积的底层前提。浏览器每次重连都会在请求头自动带上 Last-Event-ID(值为上一次收到消息的 id 字段),服务端需识别并只推送该 ID 之后的新消息。
- Spring Boot 示例:从请求参数或 header 中读取
lastId,过滤已发消息 - Node.js/Koa 示例:用
ctx.request.headers['last-event-id']获取 ID,跳过历史数据 - 切忌忽略:不处理该 header,每次重连都重推全量,积压必然发生
前端要限制缓存与处理节奏
EventSource 本身不缓存消息,但 JS 主线程若来不及处理,消息会堆积在内存中。尤其移动端或低端设备,连续几十条 JSON 解析+DOM 更新可能直接阻塞渲染。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 用
setTimeout或requestIdleCallback批量/节流渲染,避免逐条强刷 - 设置内存阈值:例如累计未处理消息超 200 条时,主动丢弃旧消息或触发告警
- 对非关键消息(如心跳、状态提示)可降级处理,优先保障核心内容流
代理层禁用缓冲是实时性的硬门槛
Nginx、CDN 或网关若开启响应缓冲,会把本该逐块输出的 event 数据攒起来,等满或连接关闭才吐出——前端看到的就是“卡顿”或“成段蹦出”,本质是数据到达时间被扭曲,间接加剧重连频率。
- Nginx 配置必须含:
proxy_buffering off;和proxy_cache off; - 后端响应头必须含:
X-Accel-Buffering: no(Nginx 专用)、Cache-Control: no-cache、Connection: keep-alive - 测试方法:用 curl -N 请求 SSE 接口,观察是否实时逐行输出,而非等待数秒后一次性返回
客户端重连策略需带熔断与退避
默认重连间隔 3 秒,在弱网下极易形成“重连风暴”。一次抖动若触发 50 次重连,而每次连接又拉取全量数据,崩溃就是必然。
- 采用指数退避:
delay = Math.min(1000 * 2^attempt, 30000) - 设置最大重试次数(如 5 次),超限后提示用户手动刷新或切换通道
- 结合
visibilitychange和online/offline事件,避免后台标签页无效重连
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










