最近在复习网络编程相关内容时,重新梳理了 HTTP 和 WebSocket 在通信模型上的根本区别。特别想搞清楚几个常被混淆的概念:为什么 HTTP 不能全双工?"等待"到底意味着什么?发请求时 CPU 会卡住吗?轮询和阻塞又是什么? 本文记录我的理解过程,便于后续面试回顾。
1. HTTP 是请求-响应模型,天然不支持全双工
全双工(Full Duplex) 指通信双方可以同时发送和接收数据,互不干扰。TCP 协议本身是全双工的,但上层应用协议是否能利用这一特性,取决于其设计。
HTTP 采用 请求-响应(Request-Response)模型:
- 客户端必须先发起请求;
- 服务器收到后才能返回响应;
- 同一连接上,一次只能处理一个请求-响应周期(在 HTTP/1.1 无管线化的情况下);
- 服务器无法主动向客户端推送数据。
因此,尽管底层 TCP 支持双向通信,HTTP 协议的设计人为限制了通信方向 ,使其表现为半双工甚至更弱的单向驱动模型。
补充:HTTP/2 引入多路复用(Multiplexing),允许多个请求/响应在同一条连接上交错传输,缓解了队头阻塞,但仍基于请求驱动,服务器不能无请求主动推送(Server Push 在 HTTP/2 中存在但已被主流浏览器弃用)。
2. "等待"是什么?CPU 会被阻塞吗?
当我们说"发完 HTTP 请求后要等待响应",这里的"等待"指的是应用程序逻辑的暂停,而非 CPU 停止工作。
关键区分:
- CPU 阻塞 :CPU 停止执行其他指令,空转等待 I/O 完成 → 现代操作系统几乎不会发生。
- 线程/任务阻塞 :当前执行流(如一个线程或协程)暂停,直到 I/O 完成 → 可能发生,但不影响系统整体性能。
实际机制:
当程序发起一个网络请求(如 fetch() 或 http.get()):
- 操作系统将该 I/O 操作交给网络子系统处理;
- 若使用同步(阻塞)I/O ,当前线程会被挂起(进入等待状态),但 CPU 会立即调度其他线程或进程执行;
- 当数据到达,操作系统通过中断通知内核,再唤醒对应线程继续执行;
- 若使用异步(非阻塞)I/O (如 JavaScript 的 Promise、Python 的 asyncio),程序立即返回,通过回调或事件循环处理结果,完全不阻塞执行流。
✅ 结论:发 HTTP 请求不会导致 CPU 闲置。真正的延迟主要来自网络传输(RTT、带宽)和服务器处理时间,而非本地计算资源浪费。
3. 轮询(Polling):模拟实时的低效方案
由于 HTTP 不支持服务器主动推送,若客户端需要获取实时更新(如新消息、股价变动),只能采用轮询:
- 定义 :客户端周期性地主动发起 HTTP 请求,询问服务器是否有新数据。
- 问题 :
- 大量无效请求(多数响应为"无更新"),浪费带宽和服务器资源;
- 实时性差:更新延迟 ≈ 轮询间隔(如每 2 秒查一次,则最大延迟 2 秒);
- 高并发下服务器压力剧增。
示例:早期 Web 聊天室每 1~2 秒发一次 AJAX 请求检查新消息。
4. 阻塞(Blocking) vs 非阻塞(Non-blocking)
- 阻塞 I/O :调用发起后,当前线程暂停执行,直到操作完成(如读取到完整响应)。常见于传统同步编程模型。
- 非阻塞 I/O :调用立即返回,程序可继续执行;结果通过回调、Promise、事件循环或轮询状态获取。是高性能服务器(如 Node.js、Nginx)的基础。
注意:"阻塞"描述的是程序执行流的行为,不是 CPU 状态。即使使用阻塞 I/O,操作系统也会让出 CPU 给其他任务。
5. WebSocket 如何解决这些问题?
WebSocket 通过以下机制实现高效实时通信:
- 一次握手,长期连接 :
初始通过 HTTP 协议升级(Upgrade: websocket),建立持久 TCP 连接。 - 全双工通信 :
连接建立后,客户端与服务器可随时主动发送数据帧,无需请求-响应配对。 - 轻量数据帧 :
帧头仅 2~14 字节,无重复 HTTP 头部,大幅降低开销。 - 无轮询、无等待 :
服务器有数据时立即推送,客户端实时接收,延迟接近网络物理极限。
此外,WebSocket 支持加密(WSS)、心跳保活、二进制传输等特性,适用于聊天、游戏、金融行情等场景。
6. WebSocket 会一直连着吗?会不会断?
不会永远连着,但比 HTTP "持久"得多。
可能断开的情况:
- 你关掉网页或 App
- 网络断了(比如地铁进隧道)
- 服务器重启
- 长时间没说话,服务器自动关闭(为了省资源)
但!好的程序会"自动重连": - 断了 → 等1秒 → 自动重新握手 → 继续聊天
- 用户几乎感觉不到中断
📱 微信、钉钉、股票软件都是这么做的!
7. WebSocket 和 HTTP 到底是什么关系?
| 对比项 | HTTP | WebSocket |
|---|---|---|
| 连接方式 | 每次请求新建连接,用完就关 | 一次连接,长期保持 |
| 通信方向 | 客户端 → 服务器(单向请求) | 双向自由通信 |
| 实时性 | 差(靠轮询模拟) | 强(真正实时) |
| 数据开销 | 大(每次带完整头部) | 小(极简帧结构) |
| 适用场景 | 看网页、下载文件 | 聊天、游戏、协作编辑、物联网 |
🔗 技术上:WebSocket 是 HTTP/1.1 协议的一个"扩展",依赖 HTTP 完成初始握手,但之后完全独立运行。
8. 现实中的例子
| 应用 | 为什么用 WebSocket? |
|---|---|
| 微信网页版 | 手机扫码后,电脑端实时收消息 |
| 股票交易软件 | 股价每秒变动,必须实时推送 |
| 在线文档(如腾讯文档) | 多人同时编辑,光标和文字实时同步 |
| 网页游戏 | 玩家移动、攻击要毫秒级响应 |
| 智能家居 App | 灯开了、门锁了,手机立刻收到通知 |
9. 术语小结(面试速记)
| 术语 | 定义 |
|---|---|
| 全双工(Full Duplex) | 双方可同时收发数据(如电话),TCP 支持,HTTP 未利用,WebSocket 充分利用。 |
| 轮询(Polling) | 客户端定期发请求查询状态,模拟实时,效率低。 |
| 阻塞(Blocking) | 当前线程因等待 I/O 而暂停执行;不等于 CPU 停止工作。 |
| 同步 vs 异步 | 同步:调用后等待结果;异步:调用后立即返回,结果通过回调等方式通知。 |
| WebSocket 握手 | 通过 HTTP 101 Switching Protocols 升级连接,后续使用独立帧协议通信。 |
写于 2026 年 1 月 14 日,为准备后端岗位面试整理。