Keep-Alive 使用场景¶
99% 的场景都该用 Keep-Alive,关键是配好超时时间和最大请求数
核心概念¶
- 高频请求 — 同一客户端短时间内多次请求同一服务器,Keep-Alive 省掉大量握手开销
- 高延迟网络 — 移动端/跨地域场景下,每次握手的延迟代价更高
- 资源受限 — 空闲连接太多时反而有害,需要缩短超时或关闭 Keep-Alive
- 安全隔离 — 某些敏感场景需要每次请求走独立连接
详解¶
建议启用 Keep-Alive 的场景¶
1. 高频请求同一服务器¶
graph LR
A[前端页面] -->|请求 30 个资源| B[CDN/源站]
C[微服务 A] -->|链式调用| D[微服务 B]
D -->|继续调用| E[微服务 C]
最常见的场景。前端页面加载、微服务间调用、API 连续请求等,几乎没有任何理由关掉 Keep-Alive。
2. 移动端 / 高延迟网络¶
移动端网络延迟高,每次 TLS 握手可能要 100-300ms:
| 场景 | 无 Keep-Alive | 有 Keep-Alive |
|---|---|---|
| 30 次请求 × 150ms 握手 | **4.5 秒**光握手 | **150ms**只握手一次 |
省了 4 秒多,体感天差地别。
3. 短间隔批量请求¶
爬虫批量抓取、定时轮询、WebSocket 建立前的 HTTP 握手等,1000 个请求:
| 方案 | 每个请求耗时 | 总耗时 |
|---|---|---|
| 无 Keep-Alive | 60ms(50ms 握手 + 10ms 传输) | 60 秒 |
| 有 Keep-Alive | 10ms(0ms 握手 + 10ms 传输) | 10 秒 |
4. 内部服务间通信¶
微服务之间的 RPC 调用、数据库连接、Redis 连接等,连接池 + Keep-Alive 是标配。
不建议使用 Keep-Alive 的场景¶
1. 一次性 / 低频请求¶
偶尔请求一次,几分钟甚至几小时才来一次:
Keep-Alive 连接空等着白白占内存。不过现代服务器默认超时 5-15 秒会自动释放,实际影响不大。
2. 连接数是瓶颈时¶
极端场景下,空闲连接太多反而有害:
这时候应该**缩短超时时间**,而不是关掉 Keep-Alive:
3. 安全隔离¶
银行转账等敏感操作,每次操作用全新连接,确保上一次的上下文不会残留。多租户 SaaS 也要隔离,A 租户的连接不能被 B 租户复用。
4. 大文件传输¶
下载 2GB 文件,一个连接独占十几分钟。如果连接池只有 10 个,其他请求全部排队等这个下载完。
# 正确做法:下载用独立连接,业务用连接池
download_session = requests.Session()
download_session.headers['Connection'] = 'close' # 下载完就关
api_session = requests.Session() # 默认 Keep-Alive
决策参考¶
| 条件 | Keep-Alive | Connection: close |
|---|---|---|
| 同一客户端高频请求 | ✅ | |
| 请求间隔 < Keep-Alive 超时 | ✅ | |
| 移动端 / 高延迟网络 | ✅ | |
| 微服务内部通信 | ✅ | |
| 偶尔请求一次 | 无所谓(让服务器默认超时就好) | |
| 单次大文件下载 | ✅ | |
| 连接数已达上限 | 缩短超时 | |
| 安全隔离要求 | ✅ | |
| 公共 API 防滥用 | 缩短超时 + 限制次数 |
生产环境配置建议¶
Nginx¶
# 后端代理(微服务间)—— 激进复用
proxy_http_version 1.1;
proxy_set_header Connection "";
keepalive_timeout 60s;
keepalive_requests 1000;
# 面向公网 —— 适度保守
keepalive_timeout 10s;
keepalive_requests 100;
Java Tomcat¶
常见陷阱¶
公共 API 忘记限制连接数
不限制 Keep-Alive 超时和最大请求数,一个恶意客户端可以长期霸占连接。应该设置 keepalive_timeout 和 keepalive_requests 上限。
大文件和小请求混用同一连接池
大文件传输独占连接时间过长,导致小请求排队。应该分离:大文件用独立连接(Connection: close),小请求用连接池复用。
练习题¶
如果你的 API 网关同时服务移动端和 Web 端,Keep-Alive 配置应该怎么考虑?
答案
移动端延迟高,Keep-Alive 收益大,超时可以设长一些(如 30 秒)。Web 端延迟低但并发高,超时可以短一些(如 10 秒)。可以按来源区分配置,或者取一个折中值(10-15 秒),配合 keepalive_requests 限制单连接最大请求数。
为什么说 Keep-Alive 的 '99% 场景都该用'?那 1% 是什么?
答案
那 1% 主要是:(1)安全隔离要求极高的场景(如金融交易),每次连接必须独立;(2)连接数是硬瓶颈的极端高并发场景;(3)超大文件传输会独占连接。除此之外,默认开启是正确选择。