启用HTTP/2需满足:Nginx≥1.9.5且编译含--with-http_v2_module、已部署有效SSL证书、443端口listen指令后添加http2参数,缺一不可。

phpEnv 默认不启用 HTTP/2,哪怕你装了 Nginx 1.20+ 且证书有效,listen 443 ssl 不加 http2 就永远是 HTTP/1.1 —— 这不是“没生效”,是压根没协商。
确认 phpEnv 的 Nginx 是否编译了 http_v2 模块
phpEnv 多数基于预编译包或一键脚本安装,不一定默认启用 HTTP/2 支持。不能只看版本号,得看实际模块是否加载:
- 执行
phpenv nginx -V 2>&1 | grep -o 'http_v2',有输出才表示模块已编译进 Nginx - 若无输出,说明当前 Nginx 是极速安装版或阉割版,
http2参数会直接被忽略,Nginx 启动时可能报the "http2" parameter requires SSL support警告(即使有证书) - phpEnv 环境下重装 Nginx 较麻烦,更现实的方案是:用
phpenv nginx -v查版本 → 若低于1.18,基本可判定不支持;推荐 ≥1.20
修改站点配置文件,只改 listen 行,别碰其他
phpEnv 的站点配置通常在 /phpenv/vhosts/域名.conf 或 /phpenv/nginx/conf/vhost/域名.conf,打开后定位到 HTTPS server 块:
- 找到类似
listen 443 ssl;的行,**仅在此行末尾加空格 +http2**,变成listen 443 ssl http2; - 如果同时监听 IPv6,补上
listen [::]:443 ssl http2;,否则 IPv6 用户仍走 HTTP/1.1 - 不要在
http块里加http2 on;—— Nginx 1.9.5+ 已废弃该指令,加了会报错 - 确保
ssl_certificate和ssl_certificate_key路径正确,且私钥未加密(openssl rsa -in privkey.pem -noout应无提示)
重载而非重启,避免服务中断
phpEnv 通常封装了 Nginx 控制命令,别直接用 systemctl 或 service:
立即学习“PHP免费学习笔记(深入)”;
- 先运行
phpenv nginx -t校验语法,避免因漏分号、多空格导致重载失败 - 校验通过后,执行
phpenv nginx -s reload(不是restart)—— reload 不断连,旧连接继续用 HTTP/1.1,新连接立即协商 HTTP/2 - 若用宝塔面板管理 phpEnv 环境,需注意:宝塔的「HTTP/2 开关」插件对非标准路径(如 phpEnv 自建 vhost)大概率失效,必须手动改配置
验证时别信 curl -I,要看浏览器真实请求
curl 默认不带 ALPN,curl -I --http2 https://yoursite.com 可能成功但不代表浏览器也走 h2;真正决定协议的是客户端 TLS 握手时的 ALPN 协商:
- Chrome / Edge 打开开发者工具 → Network → 刷新页面 → 看任意请求的
Protocol列,显示h2才算成功 - 如果显示
http/1.1,检查是否:证书域名不匹配、用了自签名证书、TLS 版本被禁(如只留了 TLSv1.3 但客户端太老)、或 Nginx 配置里混进了listen 80 http2这种非法写法 - 服务器端日志里出现
SSL_do_handshake() failed或client sent no ALPN,基本可锁定 TLS 层兼容性问题
最常被跳过的点:phpEnv 下的 Nginx 往往跑在非标准端口或反代层之后,如果前端还有 CDN 或云 WAF,它们可能终止 TLS 并降级回 HTTP/1.1 —— 此时你在 phpEnv 里配得再对,浏览器看到的仍是 h1。



















