一次讲透 HTTP 长连接:Keep-Alive 的原理、配置与避坑
【摘要】 一、为什么需要长连接每一次 HTTP 请求,底层都要经历「建立 TCP 连接 → 发送请求 → 等待响应 → 关闭连接」四个步骤。TCP 三次握手本身就要消耗 1.5 个 RTT,如果是 HTTPS,还要再叠加 TLS 握手的 1~2 个 RTT。对于高并发的接口服务来说,这些建连开销累积起来非常可观。长连接(Keep-Alive)的思路很简单:让一条 TCP 连接被多个请求复用,避免反复...
一、为什么需要长连接
每一次 HTTP 请求,底层都要经历「建立 TCP 连接 → 发送请求 → 等待响应 → 关闭连接」四个步骤。TCP 三次握手本身就要消耗 1.5 个 RTT,如果是 HTTPS,还要再叠加 TLS 握手的 1~2 个 RTT。对于高并发的接口服务来说,这些建连开销累积起来非常可观。长连接(Keep-Alive)的思路很简单:让一条 TCP 连接被多个请求复用,避免反复建连。
二、短连接 vs 长连接
短连接:每个请求独占一条 TCP 连接,响应完成后立即关闭。
长连接:连接在多次请求之间保持打开,空闲超时后才关闭。
一个容易被忽略的事实:HTTP/1.1 默认就是长连接(等价于显式声明 Connection: keep-alive),除非某一方主动声明 Connection: close。HTTP/2 则更进一步,在一条长连接上做多路复用。
三、Keep-Alive 是怎么工作的
- 客户端发起请求时带上 Connection: keep-alive;
- 服务端响应同样带上 Connection: keep-alive,还可能附带 Keep-Alive: timeout=60, max=100,表示空闲 60 秒关闭、单连接最多复用 100 次;
- 后续请求直接复用同一条 TCP 连接,不再握手;
- 空闲超过超时时间,或达到最大复用次数,任意一方都可以主动关闭连接。
四、常见配置示例
Nginx 服务端配置:
http {
keepalive_timeout 65; # 服务端空闲超时,单位秒
keepalive_requests 100; # 单条连接最多处理多少个请求
upstream backend {
server 127.0.0.1:8080;
keepalive 32; # 到后端的长连接池大小
}
}
客户端侧复用连接(curl):
curl --keepalive-time 60 -v http://example.com/api
五、避坑指南
- 超时不对称:客户端与服务端的空闲超时要协调好。典型事故是服务端先关闭了空闲连接,客户端却复用了这条已关闭的连接,结果请求报 connection reset。稳妥的做法是让客户端的超时略小于服务端。
- 负载均衡器超时:流量经过 LB 时,LB 的空闲超时往往更短(很多云厂商默认 60 秒),长连接可能被 LB 悄悄掐断,排查时记得把 LB 的配置也纳入视野。
- 连接泄漏:客户端必须完整消费响应体并归还连接,否则连接池会被占满,服务表现为「越跑越慢」,重启就好、过一阵又慢。
- 不要滥用:对低频、偶发的请求开长连接,反而长期占用服务端的文件描述符;这类场景用短连接更划算。
- HTTP/2 的多路复用:如果已经上了 HTTP/2,一条连接就能并发多个流,连接池的调优思路和 HTTP/1.1 完全不同,不要照搬。
六、总结
长连接的本质,是用「保持连接状态」换取「建连开销」。抓住超时时间、最大复用次数、关闭时机这三个关键点,再结合 Nginx、负载均衡、客户端三方的配置去排查,绝大多数 Keep-Alive 相关的线上问题都能快速定位。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)