0

Nginx HTTP/2 配置完整教程:从开启到优化的一站式实战指南

2026.05.23 | youres | 18次围观

什么是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本身的问题。排查顺序:

  1. 是否开启了TLS 1.3?(没有就加上)
  2. 是否启用了SSL会话复用?(ssl_session_cache shared:SSL:10m;
  3. 证书链是否完整?(用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辅助作者原创,未经许可,转载请保留原文链接。

发表评论