一、为什么要用 HTTP/2?
- 多路复用(Multiplexing)
单连接上可并发交错发送多路请求,避免了 HTTP/1.x 中的队头阻塞(Head-Of-Line Blocking)。 - 头部压缩(HPACK)
对 HTTP 头部字段进行高效压缩,减少冗余数据传输。 - 服务器推送(Server Push)
服务端可主动向客户端推送关联资源,减少首次加载时的 RTT。 - 单连接复用
HTTPS/TCP 握手后,所有资源都可复用同一连接,节省握手开销。
二、模块简介
-
模块名:
ngx_http_v2_module
-
引入版本:1.9.5
-
编译参数:
--with-http_v2_module
-
支持协议:
- h2(TLS + ALPN)
- h2c(明文 HTTP/2,较少使用)
三、环境与前提
- NGINX ≥ 1.9.5,推荐使用最新稳定版(≥1.25.x)。
- OpenSSL ≥ 1.0.2,需支持 ALPN 扩展。
- 在
listen
指令末尾或 server 块内启用http2
。
四、基础配置示例
server {listen 443 ssl http2; # 一行开启 HTTPS + HTTP/2server_name www.example.com;ssl_certificate /etc/ssl/server.crt;ssl_certificate_key /etc/ssl/server.key;ssl_protocols TLSv1.2 TLSv1.3;ssl_prefer_server_ciphers off; # 确保 ALPN 协商正确root /var/www/html;index index.html index.htm;# 其他 location/代理配置...
}
Tip:若使用
http2 on;
,需写在server{}
或http{}
区块内。
五、关键指令深度解读
指令 | 默认值 | 作用 | |
---|---|---|---|
listen ... http2 | — | 在 listen 末尾加 http2 即可启用 | |
`http2 on | off` | off | 全局/Server 级别开启或关闭 HTTP/2(≥1.25.1) |
http2_body_preread_size <size> | 64k | 预读请求体大小;提高大请求场景性能(≥1.11.0) | |
http2_chunk_size <size> | 8k | 响应分片大小,过大影响优先级,过小增加帧数开销 | |
http2_max_concurrent_streams n | 128 | 单连接最大并发流数 | |
http2_recv_buffer_size <size> | 256k | Worker 级输入缓冲,处理大头部请求时避免分片 | |
keepalive_timeout <time> | 75s | 代替已废弃的 http2_idle_timeout ,控制空闲连接关闭 | |
large_client_header_buffers | 4 16k | 代替已废弃的 http2_max_header_size 、http2_max_field_size |
5.1 并发流数与分片
- 并发流:过低会限制客户端并行请求数,过高占用过多内存。
- 分片大小:8–16KB 是最佳平衡,可通过
http2_chunk_size
调整。
5.2 预读请求体
对于上传或 JSON 接口,可适当增大 http2_body_preread_size
避免分次读取导致性能下降。
六、HTTP/2 Server Push 实战
6.1 静态 Push
location = /index.html {# 当客户端请求 /index.html 时,NGINX 自动 Push 关联资源http2_push /static/css/main.css;http2_push /static/js/app.js;
}
6.2 自动 Preload 转 Push
前端在响应头添加:
Link: </static/css/main.css>; rel=preload; as=style,</static/js/app.js>; rel=preload; as=script
NGINX 配置:
location / {http2_push_preload on;add_header Link "</static/css/main.css>; rel=preload; as=style";
}
注意:并非所有浏览器支持 Push。Chrome/Edge 支持,但 Firefox 近期已移除。
七、性能调优建议
- 合理并发:
http2_max_concurrent_streams
不宜超 256; - 控制推送:监测
:status=200
和 Push 成功率,避免无用浪费; - 头部压缩:保持
ssl_prefer_server_ciphers off
,SSL ciphers 符合 HTTP/2 要求; - 超时与重连:
keepalive_timeout
设为 30–60s,根据流量与内存平衡; - 监控指标:结合 NGINX Plus 或开源 Prometheus Exporter 监测 HTTP/2 连接数、流量分布。
八、常见问题排查
问题描述 | 可能原因及方案 |
---|---|
客户端回退到 HTTP/1.1 | 检查 ALPN 支持;listen ... http2 是否缺失;SSL 配置 |
Push 资源无感应 | 浏览器不支持;响应头中未包含 :status=200 ;Location 错误 |
大请求头被分片,性能下降 | 调大 http2_recv_buffer_size ;调整 large_client_header_buffers |
连接频繁重建 | 超时时间过短;keepalive_timeout 太小 |
九、实战案例分享
- 首屏加速:对首页关键 CSS/JS 使用静态 Push,首包时间降低 20%;
- 接口上传优化:API 上传接口将
http2_body_preread_size
从 64K 提升至 256K,减少多次READ
系统调用; - 监控打点:通过 NGINX 自带状态页统计 HTTP/2 连接与流数,实现流量趋势分析。
十、总结
ngx_http_v2_module
为 NGINX 带来 HTTP/2 全功能支持,结合合理配置与性能调优,可显著提升 Web 端加载速度和服务器并发承载能力。本文从环境准备、核心指令、Push 实践、性能调优和故障排查等方面进行了全面介绍,希望能帮助你在实际项目中高效落地 HTTP/2。
延伸阅读
- NGINX HTTP/2 模块官方文档
- RFC 7540: HTTP/2
欢迎在评论区留言交流更多实践经验!