SSE高并发连接限制源于浏览器同源HTTP/1.1长连接配额(默认6个),解决需三管齐下:子域名散列绕过单源限制;单连接多会话复用降低连接数;多标签页协同统一通道,并配合服务端连接池与断流自愈。

JavaScript 中 SSE 在高并发场景下遇到的连接数限制,本质是浏览器对同源(协议+域名+端口)HTTP/1.1 长连接的硬性配额控制——主流浏览器默认最多允许 6 个并发 TCP 连接。每个 new EventSource() 实例都会独占一个连接槽位,多标签页、多模块同时启用 SSE 时极易触顶,导致新连接 pending、资源加载阻塞、推送延迟甚至失败。解决不能靠“堆连接”,而要从架构层面做减法和复用。
子域名散列:绕过单源连接池限制
这是最直接、兼容性最好的方案。原理是将原本集中于 api.example.com 的 SSE 请求,分散到多个语义等价但浏览器视为不同源的子域名上,从而各自拥有独立的 6 连接配额。
- 例如把
https://api.example.com/sse拆为:https://sse1.example.com/ssehttps://sse2.example.com/ssehttps://sse3.example.com/sse - 必须确保 DNS 能解析全部子域名(推荐泛解析
*.example.com) - TLS 证书需覆盖所有子域(通配符证书
*.example.com是标配) - 子域名不携带 Cookie(设置
Domain=example.com会跨域共享 Cookie,引发请求头膨胀) - 子域数量建议控制在 3~5 个之间,过多可能触发浏览器全局 socket 总数上限
单连接 + 多会话复用:从根源减少连接数
比开多个连接更优的思路是:只建 1 条 SSE 连接,后端按业务逻辑区分数据流。一个连接承载多个用户会话或模块事件,实测可降低并发连接数 60% 以上。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 前端发起时传唯一标识:
new EventSource('/sse?sessionId=abc123&moduleId=chat') - 后端推送时带上
event:类型字段:event: chat\ndata: {"msg": "hello"}\n\nevent: notify\ndata: {"title": "更新提醒"}\n\n - 前端分别监听:
es.addEventListener('chat', handler)es.addEventListener('notify', handler) - 避免使用默认
message事件,防止不同类型消息混杂
多标签页协同:用 localStorage + BroadcastChannel 统一通道
用户打开多个同源标签页时,若每个页都建 SSE,6 个标签页就直接打满限额。应让所有标签页协商出一个“主标签页”来持有一条连接,其余页通过轻量通信共享数据。
立即学习“Java免费学习笔记(深入)”;
- 用
localStorage模拟分布式锁:各页尝试写入__sse_master__键,成功者成为主控页并创建EventSource - 主控页收到数据后,通过
BroadcastChannel广播给其他页:bc.postMessage({ type: 'sse-data', payload: data }) - 非主控页监听
BroadcastChannel,不建连接,只消费广播消息 - 主控页关闭时,其他页检测到
storage事件,重新竞选新主控
服务端配合:连接池与断流自愈
前端优化只是半程,服务端需同步支持才能真正释放并发能力:
- 后端维护 SSE 连接池,闲置连接复用而非立即销毁,降低重建开销
- 每条连接绑定 Session-ID,断连后快速恢复上下文,重连耗时 ≤50ms
- 网关层对 SSE 请求单独限流(如每 IP 每秒最多 2 个新建连接),返回标准
429和Retry-After,前端据此退避 - 响应头中添加
X-Route-Path等标识,服务端按当前活跃路由动态过滤推送,避免向已跳转页面发无效数据

















