HTTP Keep-Alive 是什么?为什么连接复用能提升性能?
简化版
HTTP Keep-Alive 指在同一个 TCP 连接上连续发送多个 HTTP 请求和响应,避免每个请求都重新建立 TCP 连接。它能减少三次握手、慢启动和 TLS 握手带来的开销。HTTP/1.1 默认持久连接,HTTP/1.0 需要显式 Connection: keep-alive。Keep-Alive 不是 WebSocket,它仍然是请求-响应模型;空闲太久的连接会被服务端或代理关闭。
详细版
没有连接复用时,每个 HTTP 请求都要经历:
TCP三次握手 -> 请求 -> 响应 -> 关闭连接
开启 Keep-Alive 后:
TCP三次握手 -> 请求1/响应1 -> 请求2/响应2 -> 请求3/响应3 -> 空闲关闭
收益包括减少连接建立延迟、降低服务器端口和连接管理开销、减少 TLS 握手成本。限制包括连接池大小、空闲超时、代理行为、队头阻塞等。HTTP/2 在一个连接上支持多路复用,比 HTTP/1.1 Keep-Alive 更进一步。
完整版教学
一、Keep-Alive 解决的核心问题
HTTP 是应用层协议,底层通常跑在 TCP 上。建立 TCP 连接需要三次握手,HTTPS 还要 TLS 握手。如果每请求一个资源就建一个连接,代价很高。
一个页面可能包含 HTML、CSS、JS、图片、字体等几十个资源:
资源1: 建连接 -> 请求 -> 响应 -> 关闭
资源2: 建连接 -> 请求 -> 响应 -> 关闭
资源3: 建连接 -> 请求 -> 响应 -> 关闭
Keep-Alive 的目标就是复用已有连接:
建连接一次 -> 请求1 -> 请求2 -> 请求3 -> 空闲后关闭
二、HTTP/1.0 和 HTTP/1.1 的差异
HTTP/1.0 默认短连接。如果要复用,需要加:
Connection: keep-alive
HTTP/1.1 默认持久连接。如果要关闭,可以显式声明:
Connection: close
这也是为什么面试里说“HTTP/1.1 默认 Keep-Alive”更准确。实际是否复用,还取决于客户端连接池、服务端超时、代理配置以及响应是否能明确边界。
三、连接复用为什么能提升性能
Keep-Alive 的性能收益来自多个层面:
| 成本 | 短连接 | Keep-Alive |
|---|---|---|
| TCP 握手 | 每次请求都要 | 多个请求共享 |
| TLS 握手 | HTTPS 下更贵 | 可减少重复握手 |
| 慢启动 | 每条新连接重新开始 | 已建立连接可继续利用拥塞窗口 |
| 服务器开销 | 频繁创建销毁连接 | 连接管理更稳定 |
尤其是 HTTPS 场景,减少 TLS 握手会明显降低延迟和 CPU 开销。
Keep-Alive 的本质不是“让 HTTP 变成长连接协议”,而是在请求-响应模型下复用底层 TCP 连接。
四、Keep-Alive 仍然有边界
连接复用不是无限持有连接。常见限制包括:
- 服务端设置空闲超时,例如 60 秒无请求就关闭;
- 代理或负载均衡设置自己的超时;
- 客户端连接池限制每个域名的最大连接数;
- 服务端可能限制单连接最大请求数;
- 网络中断或 NAT 表项过期导致连接不可用。
所以客户端复用连接前,需要能处理“对端已经关闭”的情况。工程里常见做法是连接池健康检查、失败重试和合理超时。
五、HTTP/1.1 Keep-Alive 和队头阻塞
HTTP/1.1 虽然能复用连接,但同一连接上的请求和响应通常仍要按顺序处理。即使支持管线化,响应顺序也不能乱。
请求1 -> 请求2 -> 请求3
响应1 很慢
响应2、响应3 即使准备好了也可能被挡住
这就是 HTTP/1.1 层面的队头阻塞问题。HTTP/2 用多路复用在一个连接上并发多个 stream,缓解了这个问题;但 TCP 层丢包仍可能影响同一连接里的多个 stream。
六、它和 WebSocket、HTTP/2 的区别
| 技术 | 连接特点 | 通信模型 |
|---|---|---|
| HTTP/1.1 Keep-Alive | 复用 TCP 连接 | 请求-响应 |
| WebSocket | 建立后长期保持 | 全双工消息通信 |
| HTTP/2 | 单连接多路复用 | 多 stream 请求-响应 |
Keep-Alive 不会让服务端随时主动推业务消息;它仍然主要由客户端发起请求、服务端返回响应。
七、常见误区与追问
- 误区:Keep-Alive 等于 WebSocket。 Keep-Alive 只是复用 TCP 连接,仍然是 HTTP 请求-响应模型。
- 误区:HTTP/1.1 每个请求都必须新建 TCP。 HTTP/1.1 默认持久连接,通常可复用连接。
- 误区:连接复用就不会超时关闭。 空闲超时、最大请求数、代理策略都可能关闭连接。
- 误区:Keep-Alive 可以解决所有队头阻塞。 HTTP/1.1 仍可能有应用层队头阻塞,HTTP/2 多路复用进一步缓解。
- 追问:为什么 HTTPS 更需要连接复用? 因为除了 TCP 握手,还有 TLS 握手和证书校验等额外开销。
- 追问:服务端如何知道一个响应结束? 靠
Content-Length、chunked 结束块或关闭连接等方式明确边界。
八、加强记忆
Keep-Alive 记住三句话:HTTP/1.1 默认持久连接;它复用 TCP 连接,减少握手、慢启动和 TLS 成本;它不是 WebSocket,仍然是请求-响应。排障时关注连接池、空闲超时、代理超时、响应边界和重试机制。谈到 HTTP/2 时再补充多路复用,就能把性能和协议演进讲完整。