什么是HTTP/2?为什么要用它
HTTP/2是HTTP/1.1的升级版,最大的变化是多路复用(Multiplexing)——多个请求可以在同一个TCP连接上并行传输,彻底解决了HTTP/1.1的队头阻塞问题。
实际测试中,开启HTTP/2后,页面加载时间通常能缩短30%~50%,尤其是资源多的网站效果更明显。它还有头部压缩(HPACK)、服务端推送、请求优先级等特性,都是HTTP/1.1不具备的。
开启HTTP/2前的准备工作
SSL证书是必须的吗
现实中,浏览器只支持HTTPS上的HTTP/2(h2),纯HTTP的HTTP/2(h2c)基本没人用。所以你需要:
- 一张有效的SSL证书(Let's Encrypt免费证书就够用)
- Nginx已配置好SSL监听(listen 443 ssl)
Nginx版本要求
HTTP/2模块从Nginx 1.9.5开始内置,不需要额外编译。检查你的版本:
nginx -v
如果版本低于1.9.5,先升级Nginx。主流仓库(apt/yum)里的版本都早已满足要求。
OpenSSL版本检查
HTTP/2 over TLS依赖ALPN(Application-Layer Protocol Negotiation)扩展,这个需要OpenSSL 1.0.2以上。查看版本:
openssl version
如果输出是OpenSSL 1.0.1或更老,需要升级OpenSSL,否则客户端无法协商到HTTP/2,会降级到HTTP/1.1。
Nginx HTTP/2 基础配置实战
最简单的开启方式
在listen指令后面加上http2参数即可:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# 其他配置...
}
就这一行改动,Nginx会在TLS握手时通过ALPN告知客户端支持HTTP/2,握手完成后直接用HTTP/2协议通信。
同时支持HTTP/1.1和HTTP/2
不需要做任何额外配置——客户端不支持HTTP/2时,会自动降级到HTTP/1.1。你只需要保证listen 443 ssl http2;这一行写对,兼容性由Nginx自动处理。
完整配置示例
server {
listen 443 ssl http2;
listen 80;
server_name www.youres.cn youres.cn;
# SSL配置
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# 80端口跳转HTTPS
if (\ = http) {
return 301 https://\System.Management.Automation.Internal.Host.InternalHost\;
}
root /var/www/html;
index index.html index.php;
location / {
try_files \ \/ =404;
}
}
HTTP/2 关键指令详解
Nginx从1.25.1版本开始,HTTP/2相关的指令写法有变化,老版本用http2 on/off,新版本改为直接在listen后面加http2参数。下面按新版本写法说明。
http2_max_concurrent_streams —— 并发流控制
http2_max_concurrent_streams 128;
默认值128,意思是每条TCP连接上最多同时开放128个HTTP/2 Stream(流)。如果你的网站资源特别多(比如一个页面要加载200+个文件),可以适当调大。但别设太大,会消耗更多内存。
经验值:小网站默认128够用;大流量网站可以设到256。
http2_chunk_size —— 分块大小调整
http2_chunk_size 8k;
默认8KB,Nginx把响应体切成多个chunk分帧发送。这个值太小会增加帧头开销;太大则会影响优先级调度(HOL阻塞风险)。一般保持默认即可,除非你明确知道在调什么。
http2_body_preread_size —— 请求体预读
http2_body_preread_size 64k;
默认64KB,Nginx在开始处理请求前,会先把请求体缓存这么多。对于上传文件的场景,如果文件超过64KB,Nginx会边接收边处理,不走预读。一般不用改。
http2_recv_buffer_size —— 接收缓冲区
http2_recv_buffer_size 256k;
这是http层级的指令(不是server层级),设置每个worker进程接收HTTP/2连接的缓冲区大小。默认256KB,高并发场景下可以适当调大,比如:
http {
http2_recv_buffer_size 512k;
# 其他配置...
}
HTTP/2 性能优化参数
SSL/TLS优化配合HTTP/2
HTTP/2对TLS的要求更高,建议开启TLS 1.3(减少握手往返),并启用OCSP Stapling:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_stapling on;
ssl_stapling_verify on;
关于SSL性能调优的完整实战,可以看这篇:Nginx SSL/TLS 性能优化实战。
开启Gzip压缩
HTTP/2不排斥压缩,Gzip依然有效(HPACK是头部压缩,Gzip是内容压缩,两者不冲突):
gzip on;
gzip_comp_level 5;
gzip_min_length 1k;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
调整keepalive参数
HTTP/2连接是复用的,keepalive的意义从"减少TCP握手"变成了"维持Stream通道"。调整:
keepalive_timeout 300s; # 连接保持5分钟
keepalive_requests 1000; # 每条连接最多处理1000个请求
检测HTTP/2是否生效的5种方法
配置完了,怎么确认HTTP/2真的生效了?详细方法可以参考:如何检测网站是否开启HTTP/2。
这里给一个最快的验证方式——用curl:
curl -I --http2 -s https://www.youres.cn | grep -i "HTTP/2"
如果输出包含HTTP/2 200,说明HTTP/2已生效。
Chrome用户可以在DevTools的Network面板里,Mouse over到Protocol列(默认不显示,需要右键表头勾选),看到h2就是成功。
常见问题排查
开启后访问反而变慢?
这种情况通常是TLS配置不当导致的,不是HTTP/2本身的问题。排查顺序:
- 是否开启了TLS 1.3?(没有就加上)
- 是否启用了SSL会话复用?(
ssl_session_cache shared:SSL:10m;) - 证书链是否完整?(用SSL Labs测试看一下)
详细排查步骤参考:Nginx开启HTTP/2后访问慢?问题排查与性能优化完整指南。
浏览器不支持HTTP/2怎么办?
不需要担心,Nginx会自动降级到HTTP/1.1,用户无感知。你可以从Nginx访问日志里看到协议版本:
log_format main '\ - \';
access_log /var/log/nginx/access.log main;
\变量的值:h2(HTTP/2 over TLS)、h2c(HTTP/2 cleartext)、空字符串(HTTP/1.x)。
混合内容(Mixed Content)问题
HTTPS页面里引用了HTTP资源,浏览器会拦截。开启HTTP/2后这个问题更突出,因为Chrome对HTTP/2页面的Mixed Content限制更严格。解决方法是把所有外部资源链接改成https://或使用协议相对URL(//cdn.example.com/xxx)。
生产环境完整配置模板
把上面提到的配置整合到一起,直接可用的生产级模板:
http {
http2_recv_buffer_size 512k;
server {
listen 443 ssl http2;
listen 80;
server_name example.com;
# SSL
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:HIGH:!aNULL:!MD5';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
# HTTP/2 参数
http2_max_concurrent_streams 256;
# 80跳转HTTPS
if (\ = http) {
return 301 https://\System.Management.Automation.Internal.Host.InternalHost\;
}
# Gzip
gzip on;
gzip_comp_level 5;
gzip_min_length 1k;
# keepalive
keepalive_timeout 300s;
keepalive_requests 1000;
root /var/www/html;
index index.html;
}
}
总结
开启Nginx的HTTP/2只需要改一行配置(listen 443 ssl http2;),但要让它真正发挥性能,还需要配合SSL优化、Gzip压缩、keepalive调优一整套工作。建议先在测试环境验证,确认无问题后再推到生产环境。
如果你对HTTP/2的多路复用底层原理感兴趣,可以看这篇:HTTP/2 多路复用工作原理:让网站速度翻倍的核心技术。
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论