nginx中http/2多路复用必须在server块的listen指令中内联声明为“listen 443 ssl http2”,不可分离或全局配置;需同时满足https、alpn支持(tls≥1.2)及可信证书三条件,协商成功后自动启用。

Nginx 中没有 listen_http2 指令,这是一个常见误解。HTTP/2 的多路复用不能通过独立指令(如 http2 on 或 listen_http2)在 http 块或 server 块外“全局开启”,它必须在 server 块的 listen 指令中显式、内联地声明,且仅对启用 TLS 的 HTTPS 服务生效。
真正起作用的写法只有一种:
listen 443 ssl http2;
这行配置必须同时满足三个条件:
- 端口为 443(或其他启用 TLS 的端口)
- 包含
ssl关键字(表示启用 TLS) -
http2与ssl出现在同一行listen指令中,不可拆分、不可换行、不可写在别处
例如,以下写法全部错误或无效:
-
listen 443 ssl;→ 缺少http2,仍走 HTTP/1.1 -
listen 443 http2;→ 缺ssl,Nginx 启动报错(HTTP/2 不允许明文) -
listen 443 ssl;http2 on;→http2 on不是合法指令,会被忽略或报错 -
listen [::]:443 ssl http2;但证书路径未配置或权限不足 → 协商失败,浏览器降级
必须配套的 HTTPS 基础配置
仅加 http2 不够,还需确保 TLS 层支持 ALPN 协商 h2 协议名:
- 使用有效、可信的证书(Let’s Encrypt 全链证书推荐)
-
ssl_certificate指向fullchain.pem(非仅cert.pem) -
ssl_certificate_key指向私钥,且 Nginx worker 有读取权限 - 启用 TLS 1.2 或更高版本:
ssl_protocols TLSv1.2 TLSv1.3; - 确保 OpenSSL ≥ 1.0.2(推荐 1.1.1+ 或 3.x),Nginx ≥ 1.9.5(推荐 1.20+)
多路复用是否生效?看这里
不需要额外开启,只要协议协商成功,多路复用即自动启用:
- 浏览器打开 DevTools → Network 标签 → 刷新页面 → 查看任意请求的 Protocol 列显示
h2 - 终端执行:curl -I --http2 https://www.php.cn/link/da5ac2a4989f1ac70e4dec5ae331f9ca → 返回首行含 HTTP/2 200
- Wireshark 抓包过滤
http2,可观察同一 TCP 流中多个Stream ID的HEADERS帧交错发送
不复杂但容易忽略:多路复用是协议协商结果,不是开关功能;它依赖客户端支持、服务端正确配置、TLS 层 ALPN 成功通告 h2 —— 缺一不可。











