← 中文资源

简体中文版本

在 NGINX 上通过 ALPN 启用 HTTP/2

为现有 HTTPS 站点启用 HTTP/2:编译模块检查、ALPN 协商、配置 http2 指令,并用 curl 验证实际协商协议。

阅读英文原文

概述

HTTP/1.1 在每个连接上串行处理请求,浏览器通常会为同一域名建立多条连接,且每个请求都携带完整头部。HTTP/2 在一条 TLS 连接上多路复用多个流,并用 HPACK 压缩头部,因此对头部多、请求密集的 API 收益明显。迁移目标是让客户端通过 ALPN 协商到 h2,同时保留 HTTP/1.1 回退能力。

步骤

  1. 先确认运行中的 NGINX 已编译 ngx_http_v2_module:nginx -V 2>&1 | tr " " "\n" | grep http_v2。若输出包含 --with-http_v2_module,说明无需重新编译。
  2. 修改 TLS 虚拟主机配置。NGINX 1.25.1 起使用独立的 http2 on; 指令,不再把 http2 写在 listen 后面:
server {
  listen 443 ssl;
  server_name api.example.com;
  http2 on;
  ssl_certificate     /etc/nginx/tls/api.example.com.crt;
  ssl_certificate_key /etc/nginx/tls/api.example.com.key;
}
  1. 执行 nginx -t && systemctl reload nginx,用 reload 而不是 restart,让 worker 处理完存量请求。
  2. 用 curl -sI --http2 https://api.example.com/health | head -n 1 检查返回行。

验证

预期状态行为 HTTP/2 200。如果仍是 HTTP/1.1 200,依次排查:客户端 curl 是否支持 HTTP/2、TLS 是否被 CDN 或负载均衡器提前终止、配置是否真正加载。也可以用 openssl s_client -alpn h2 -connect api.example.com:443 观察 ALPN 协商结果。

注意事项

  • NGINX 1.25.1 之前必须写 listen 443 ssl http2;,否则会报未知指令。
  • 后端仍可使用 HTTP/1.1,proxy_http_version 1.1 与 proxy_set_header Connection "" 保持长连接即可。
  • HTTP/2 只优化连接层,不会修复慢查询或慢后端;上线前后应各做一次压测对比。
  • 浏览器强制要求 TLS,h2c 仅适合内网服务间通信。