http/2多路复用需客户端到nginx和nginx到后端双链路协同:前者调优keepalive_timeout(30–60s)与keepalive_requests(1000–5000),后者须upstream启用https://、proxy_http_version 2.0、keepalive 16–64并清除upgrade/connection头,同时调大http2_max_concurrent_streams至256–512。

HTTP/2 的多路复用能力不是开个 http2 就自动生效的,它高度依赖底层 TCP 连接的稳定性与复用深度。KeepAlive 参数正是控制这个“连接池厚度”的关键开关——配得浅,stream 频繁挤在新连上;配得深,又可能压垮后端。真正压榨传输极限,要让每个 TCP 连接尽可能承载更多并发 stream,同时不引发资源争抢。
客户端到 Nginx:稳住入口长连接
这是多路复用的第一道基础。Nginx 默认已开启 client keepalive,但默认值(keepalive_timeout 75s、keepalive_requests 100)对高并发或大资源站点偏保守:
- keepalive_timeout 建议设为 30–60 秒:比后端服务超时小 5–10 秒更稳妥,避免 Nginx 主动断连而客户端还等着复用;过长(如 300 秒)易堆积空闲连接,占用 worker 进程 fd 资源。
-
keepalive_requests 可调至 1000–5000:尤其适合静态资源多、单页请求数高的场景;但注意,该值过高会延长单连接生命周期,在 QPS 极高时反而增加内存压力,需结合
worker_connections综合评估。 - 确保前端发起请求时带
Connection: keep-alive,现代浏览器默认满足,但某些 SDK 或测试工具可能忽略。
Nginx 到后端:必须启用 HTTP/2 + keepalive 池
仅客户端走 HTTP/2 是半截子优化。若 Nginx → 后端仍用 HTTP/1.1 短连,所有多路请求最终被串行化转发,复用红利全丢在反代层:
-
upstream 必须用
https://协议,并显式设置proxy_http_version 2.0;http://地址强制降级为 HTTP/1.1。 -
upstream 块内加
keepalive 32(推荐范围 16–64):这表示最多保留 32 个空闲 HTTPS 连接供复用;数值太小(如 2)导致频繁 TLS 握手和建连开销;太大(如 >100)易触发后端连接数告警或拒绝。 - 配套清理升级头:
proxy_set_header Connection '';和proxy_set_header Upgrade '';,防止 HTTP/1.1 兼容逻辑干扰 HTTP/2 帧解析。
帧级与连接级协同调优
HTTP/2 多路复用效果最终体现在帧(Frame)调度效率上,这需要连接参数与协议参数联动:
-
调大
http2_max_concurrent_streams(默认 128):建议设为 256 或 512,允许单连接承载更多并行 stream;但需确认后端(如 Go net/http、Node.js http2)也同步放宽限制,否则会被上游截断。 -
配合
keepalive_timeout调整系统内核参数:例如 Linux 的net.ipv4.tcp_fin_timeout和net.core.somaxconn,避免 TIME_WAIT 积压或连接队列溢出,间接保障 keepalive 连接池可用性。 - 禁用
http2_idle_timeout过短值(默认 3m),若业务存在间歇性低流量,可适当延长,减少连接重建频率。
验证是否真正在“压榨”而非“假跑”
别只看响应头写着 HTTP/2 200。真实压榨极限的表现是:多个资源复用同一 connection ID,且在 Wireshark 或后端日志中可见交错的 HEADERS + DATA 帧:
- 浏览器 Network 面板勾选
Protocol列,观察同域名下多个 JS/CSS 是否都显示h2; - 用
curl -I --http2 https://yoursite.com确认协商成功; - 后端启用 HTTP/2 日志(如 Node.js 的
http2模块 debug 日志),检查是否收到多个 stream ID 共享同一 socket。











