HTTP 网络通信的两种核心模式,一张图彻底搞懂
客户端发送每个 HTTP 请求之前,都要先完成一次完整的三次握手(SYN → SYN+ACK → ACK),请求结束后立刻四次挥手断开。
TCP 握手和挥手需要额外的 RTT 往返时间。假设网络延迟 50ms,每次请求额外消耗至少 150ms(3次RTT)在连接管理上。
服务端无需维护连接状态,天然无连接泄漏风险。故障隔离好——某个连接出问题不影响后续请求。
低频请求
静态资源
传统Web页面
API网关
如:用户偶尔查询一次天气、加载一个不常访问的页面。
建立一次 TCP 连接后,可以在同一条连接上连续发送多个 HTTP 请求和响应。省去重复的三次握手开销。
消除了重复握手的 RTT 开销。对于需要频繁交互的场景(如加载一个含大量资源的网页),速度提升非常明显。
服务端需要维护活跃连接列表,设置空闲超时机制(如 Nginx 默认 keepalive_timeout=65s),防止僵尸连接占用资源。
高频API调用
WebSocket
HTTP/2多路复用
数据库连接池
如:SPA应用、实时聊天、gRPC、移动App后端接口。
| 对比维度 | 🔶 短连接 (Short Connection) | 🟢 长连接 (Long Connection) |
|---|---|---|
| TCP 连接方式 | 每个请求新建一个连接,用完即销毁 | 一次建连,多次复用同一条连接 |
| 默认协议 | HTTP/1.0 默认模式Connection: close |
HTTP/1.1 Keep-Alive / HTTP/2Connection: keep-alive |
| 握手次数(3个请求) | 3 次 TCP 三次握手 + 3 次四次挥手 = 21 个包 | 1 次三次握手 + 1 次四次挥手 = 7 个包 |
| 请求延迟 | 高 — 每次请求额外增加 ~1.5 RTT 握手时间 | 低 — 后续请求几乎无额外开销 |
| 服务端资源占用 | 瞬时连接数波动大,但无长期占用 | 需持续维护连接池,占用更多内存/fd |
| 服务器压力 | CPU 密集型 — 频繁创建/销毁连接 | 内存密集型 — 维护大量长连接状态 |
| 实现复杂度 | 简单 — 无需维护状态 | 复杂 — 需要心跳检测、超时管理、负载均衡策略 |
| 故障影响范围 | 小 — 单连接故障只影响当前请求 | 大 — 一条长连接断开可能中断多个待发请求 |
| 典型应用 | 早期 Web 浏览器、传统 CGI、简单 API 调用 | 现代浏览器、移动 App、WebSocket、gRPC、HTTP/2 |
| 生活类比 | 📞 每次打电话说完就挂断,下次再打 | 📞 打通电话后一直不挂,有事直接说 |
打开一个网页平均需要加载 20~80 个资源(JS/CSS/图片/字体)。如果用短连接,光是握手就要几十到上百毫秒。HTTP/1.1 默认开启 Keep-Alive,HTTP/2 更是在一条连接上做多路复用,彻底解决了队头阻塞问题。
keepalive_timeout 65; — 空闲超时时间
keepalive_requests 1000; — 单连接最大请求数
超过任一限制就会关闭连接。合理配置可以兼顾性能与资源利用率。
长连接不是真的永远保持!它有超时机制:服务端设置 keepalive_timeout,超过空闲时间就主动断开。客户端也需要做心跳检测(如 WebSocket 的 ping/pong)来保活。