system-design-notes:长轮询、短轮询、SSE、WebSocket,实时通信4种方案终极对比
【免费下载链接】system-design-notesNotes of the book System Desgin Interview - An Insider's Guide项目地址: https://gitcode.com/GitHub_Trending/sy/system-design-notes
system-design-notes 是基于《System Design Interview - An Insider's Guide》整理的系统设计面试笔记开源项目,其中「Design A Chat System」与「Design Google Maps」章节系统性地对比了短轮询、长轮询、SSE(Server-Sent Events)和 WebSocket 四种实时通信方案。本文提炼笔记精华,带你一次性搞清楚:这 4 种实时通信方案各自怎么工作、优劣在哪、真实生产环境该选谁。🎯
为什么需要实时通信?
以聊天系统为例,发送方把消息交给聊天服务(存储并转发),接收方必须尽快收到。但浏览器本质上是"请求-响应"模型——客户端只能主动问,服务器无法主动"敲门"。如何打破这个限制?业界的答案就是下面 4 种方案,复杂度与实时性依次递增。👇
短轮询:最简单粗暴的实时通信方式
客户端每隔固定时间向服务器发一次请求:"有新消息吗?"服务器立刻回答"有/没有",连接随即关闭。轮询间隔内没有新消息就继续等下一轮。

优点:实现极简,纯 HTTP 短连接,对代理、防火墙友好,兼容性最好。
缺点:
- 延迟高:最坏情况下要等一个完整轮询周期才能收到消息
- 大量无效请求:如上图所示,绝大多数回答都是 "NO",白白消耗带宽
- 频繁建立/断开连接,服务器开销大
长轮询:低延迟的"过渡方案"
长轮询改进了"空等"问题:客户端发起请求后,服务器不立刻回复,而是把连接挂起,一直等到新消息产生(或超时)才返回。客户端收到响应后立刻发起下一次请求,如此循环,形成"伪推送"效果。

优点:
- 延迟远低于短轮询(消息一到就返回)
- 依然是标准 HTTP,兼容性好
缺点:
- 对不活跃用户不友好:连接被长时间挂起,占用服务器资源(原笔记原文:Inefficient for inactive users)
- 本质上仍是客户端单向拉取,每轮都要重新走一遍请求
- 超时、代理缓冲等边界情况需要额外处理
SSE:浏览器原生的服务器推送
SSE(Server-Sent Events)基于普通 HTTP:客户端发起一次请求后,服务器保持连接打开,持续向下推送文本事件流,浏览器通过内置的EventSourceAPI 接收。
优点:
- 真正的服务器→客户端单向推送,延迟低
- 浏览器原生支持,内置自动重连,并可通过
Last-Event-ID断点续传 - 走 HTTP 协议,部署简单
缺点:
- 只能单向(服务器→客户端),客户端上行仍需额外通道
- 只传文本,不支持二进制
- 同一域名的并发连接数受浏览器限制
适用场景:股票行情、新闻推送、进度通知等"服务器播报、用户只听"的场景。📈
WebSocket:全双工双向通信的终极方案
WebSocket 通过一次 HTTP 握手(Upgrade)后,把连接升级为ws协议,建立全双工持久连接:连接建立后,客户端和服务器可以随时互发消息,无需反复请求。

优点:
- 真正双向、低开销(轻量帧头,支持二进制),延迟最低
- 一次握手,长期复用,连接数远少于轮询方案
缺点:
- 连接是有状态的:服务器必须长期持有连接,扩容、故障转移、服务发现都要专门设计
- 心跳保活、断线重连、负载均衡粘滞会话等都要自己处理
4种方案一张表看懂
| 维度 | 短轮询 | 长轮询 | SSE | WebSocket |
|---|---|---|---|---|
| 通信方向 | 客户端拉取 | 客户端拉取 | 服务器单向推送 | 全双工双向 |
| 连接模型 | 短连接,反复开关 | 挂起等待 | 长连接 | 持久连接 |
| 实时性 | 低(≤轮询间隔) | 较低 | 低 | 最低 ⚡ |
| 服务器开销 | 高(无效请求多) | 中 | 低 | 低(连接状态需管理) |
| 浏览器支持 | 全 | 全 | 良好(单向) | 全 |
| 典型场景 | 简单状态检查 | 遗留系统、代理受限环境 | 行情、通知、进度 | 聊天、游戏、协同编辑 |
到底怎么选?实战选择指南
结合笔记中 Google Maps 章节的真实决策逻辑(位置更新如何主动推给客户端):
- 单向推送为主(导航提醒、状态播报):SSE 就够了,实现成本低
- 需要双向高频交互(聊天、多人游戏、实时协作):选 WebSocket。Google Maps 笔记原文:"We can also use server-sent events (SSE) but lean towards web sockets as they support bi-directional communication"——正是看中了双向通信在"最后一公里配送"这类场景的灵活性
- 老系统 / 严格代理环境:长轮询兜底
- 快速验证或资源极受限:短轮询
实战案例:聊天系统中如何落地 WebSocket
system-design-notes 的「Design A Chat System」章节(5000 万 DAU 规模)给出了完整的工程化设计,值得对照学习:

1. 无状态 + 有状态服务分层:注册、登录、用户资料等走无状态 API 服务;聊天服务器(Chat Server)专门持有 WebSocket 持久连接,负责消息投递。服务发现组件(如 Zookeeper)根据地理位置和负载,为客户端挑选最优聊天服务器。
2. 心跳机制判断在线状态:客户端每 5 秒向 presence 服务器发一次心跳;若 30 秒未收到心跳,即标记为离线。

3. 在线状态扇出(Fanout):用户 A 的上下线状态变更,通过发布-订阅模型发布到 A-B、A-C、A-D 等频道,好友 B、C、D 各自订阅对应频道,实时收到状态更新。

这正是 WebSocket 方案的完整闭环:持久连接负责消息投递,心跳负责存活检测,pub/sub 负责状态广播。💬
项目内相关资料
- 聊天系统设计全章:12. Chat System/Readme.md
- 位置更新推送协议对比(SSE vs WebSocket vs 长轮询):18. Google Maps/README.md
- 全书章节目录(28 章系统设计):Readme.md
掌握这 4 种实时通信方案的取舍逻辑,是系统设计面试(聊天、协同、IM、行情类题目)绕不开的基本功。建议对照原文反复看图理解时序细节,面试时能画出上图这几张时序图,基本就赢了一半。🚀
【免费下载链接】system-design-notesNotes of the book System Desgin Interview - An Insider's Guide项目地址: https://gitcode.com/GitHub_Trending/sy/system-design-notes
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考