LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

Nginx 之 v2 模块,告别HTTP1.1,开启多路复用与资源推送

admin
2026年1月11日 10:31 本文热度 276

Nginx 中 http2 协议介绍与服务搭建资源推送

描述:前面《Nginx | HTTP 反向代理:gRPC 高性能远程过程调用(RPC)框架》文章中,我们介绍了 Google 推出的 gRPC 服务框架,并在 Nginx 反向代理 gPRC 服务时它也是基于 HTTP/2 实现的,HTTP2.0 协议相对于 HTP1.1 协议有很大的一个性能提升。另外,作者前面的 Nginx 演示配置中都开启了 HTTP/2 支持,但是并未对其详细介绍,和对性能到底有那些提升,以及演示其资源推送功能,所以接下来我们一一详细介绍与实践。


HTTP2 协议介绍

HTTP/2 是 HTTP 协议的第二个主要版本,于 2015 年发布,旨在解决 HTTP/1.x 的性能瓶颈,提升网页加载速度和网络效率,解决了队头阻塞(HTTP/1.x 中一个请求阻塞后续请求),高延迟(减少多次 TCP 连接和握手开销)以及头部冗余(重复的头部字段占用带宽),显著提升了 Web 性能,HTTP/2  已成为现代互联网的主流协议被广泛使用。

weiyigeek.top-作者个人网站启用HTTP/2.0图

HTTP/2.0 协议的核心概念:

  • 连接(Connection):单个 TCP 连接,可以承载多个双向数据流(Stream)

  • 流(Stream):双向通讯的数据流,每个页面可能对应一个Stream,每个流可以包含多个消息

  • 消息(Message):每个消息包含1个或多个帧,对应 HTTP/1.x 请求和响应

  • 帧(Frame):最小概念单元,以二进制压缩格式存储 HTTP/1.x 内容,包括 Headers 和 Data

weiyigeek.top-HTTP/2.0 协议的核心与分层图

此文,我们再详细的介绍一下 Frame 帧的格式,如下图所示:包含长度、类型、标识,消息号(4字节32位)以及数据内容等。

weiyigeek.top-HTTP/2.0 协议帧格式图

HTTP/2 主要特性与改进:

  • [x] 二进制传输(核心): 将文本格式(HTTP/1.x)改为二进制格式,解析更快、更高效,且减少错误。

  • [x] 头部压缩(核心): 使用 HPACK 算法压缩请求头,减少冗余数据(如 Cookie、User-Agent),降低带宽消耗,例如:相似请求间仅传输变化部分,大幅度减少重复头部信息的传输,算法主要包含三个部分:

    • 静态字典:将常用的 header 字段整成字典,比如 {"method":"GET"} 就可以用单个数字 2 来表示。
    • 动态字典:没有在静态字典里面的一些头部字段,则用动态字典。
    • Huffman 编码:压缩编码。

weiyigeek.top-HTTP/2.0 头部压缩图

  • [x] 多路复用(核心): 允许在单个 TCP 连接上并行传输多个请求和响应,即传输中无序,接收时组装(利用缓存),解决了 HTTP/1.x 的队头阻塞问题,大幅提升并发效率,减少了我们的三次握手和四次握手的开关连接的一个过程,工作效率也最高。

weiyigeek.top-HTTP/2.0 多路复用图

  • [x] 服务器资源推送: 服务器可以主动向客户端并行推送资源(如 HTML、CSS、JS),减少额外的请求延迟,

weiyigeek.top-HTTP/2.0 资源推送图

  • [x] 自定义资源优先级:允许客户端为请求分配优先级,确保重要资源(如 HTML)优先传输,例如在某些场景中CSS 可能对重要,需要先给浏览器进行渲染。

weiyigeek.top-HTTP/2.0 资源优先级图

  • [x] 更安全的默认要求:主流浏览器仅支持加密的 HTTP/2(基于 TLS/1.2+),即必须SSL全站加密,而非明文传输才能真正使用 HTTP/2。

HTTP/2.0 与 HTTP/1.x 对比如下表格所示:

特性HTTP/1.0HTTP/1.1HTTP/2说明与影响
协议格式
文本协议
文本协议
二进制协议
HTTP/2使用二进制帧传输,解析效率更高,错误率更低
连接管理
短连接(默认)
持久连接(默认)
单连接多路复用
HTTP/2单个TCP连接可处理多个并行流,减少连接开销
并发请求
每个请求需新连接
多个TCP连接(6-8个/域名)
单个连接内多路复用
HTTP/2彻底解决队头阻塞,无需域名分片等优化技巧
头部传输
不压缩
不压缩
HPACK头部压缩
减少重复头部传输(如Cookie、User-Agent),节省带宽40-90%
数据压缩
可选(如gzip)
可选(如gzip)
可选(如gzip)
主体压缩方式不变,但HTTP/2有更好的整体压缩
服务器推送
不支持
不支持
支持(主动推送)
服务器可预测客户端需求,提前推送CSS/JS等资源
请求优先级
流优先级控制
客户端可指定资源加载优先级(如HTML优先于图片)
队头阻塞
严重
存在(管道化很少用)
基本解决(应用层)
HTTP/2仍受TCP队头阻塞影响,但应用层已优化
安全要求
事实上的TLS要求
主流浏览器只支持加密的HTTP/2(h2),非加密的h2c较少用
握手开销
高(每次新连接)
中等(持久连接)
低(复用连接)
HTTP/2减少TCP和TLS握手次数,提升加载速度
协议协商
Upgrade机制
ALPN扩展
通过TLS的ALPN在握手时协商HTTP/2,无需额外往返
错误处理
关闭连接
关闭连接
更精细的连接控制
支持重置流(RST_STREAM)而不关闭整个连接
流量控制
基于TCP
基于TCP
基于流的流量控制
为每个流单独控制流量,更灵活的资源管理
典型延迟
中等
多路复用和头部压缩显著减少页面加载时间
头部大小限制
无明确规定
无明确规定
更高效处理大头部
使用索引表管理头部字段,避免重复传输
缓存策略
基础支持
增强(ETag等)
同HTTP/1.1
缓存机制继承HTTP/1.1,无本质改变
weiyigeek.top-http1.0VS2.0图

另外,HTTP/2 为 HTTP/3 奠定了基础,HTTP/3 改用 QUIC 协议(基于 UDP),进一步解决 TCP 的队头阻塞和连接延迟问题。

好了,上面我们介简单绍了 HTTP/2.0 相关特性以及与 HTTP 1.x 协议的对比,下面我们将在 Nginx 中搭建一个 HTTP/2.0 服务,查看到 HTTP 2.0 的优势,并演示其资源推送功能,不过在此之前,同样先简单的介绍在 Nginx 中 HTTP/2.0 相关指令配置。

Nginx HTTP/2 模块指令

在 Nginx 中要完全支持 HTTP/2.0 相关功能,需在编译时启用 --with-http_v2_module 选项,以安装 ngx_http_v2_module 模块,其次必须开启 TLS/SSL 协议,需申请并配置SSL证书(如通过Let's Encrypt、自签证书),ngx_http_v2_module 帮助文档地址 https://nginx.org/en/docs/http/ngx_http_v2_module.html

# 构建脚本 Makefile
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --sbin-path=/usr/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --error-log-path=/var/log/nginx/logs/error.log --http-log-path=/var/log/nginx/logs/access.log --lock-path=/var/run/nginx.lock --modules-path=/usr/local/nginx/modules --with-http_stub_status_module --with-http_realip_module  --with-http_ssl_module --with-http_slice_module --with-http_v2_module --with-cc-opt=-O2 --with-compat

# 编译安装
make -j$(nproc) && make install


指令模块

http2 指令用于启用 HTTP/2.0 支持,默认情况下是关闭的。

Syntax: http2 on | off;
Default: http2 off;
Context: http, server
This directive appeared in version 1.25.1. 

# 基础示例
server {
  listen 443 ssl;  # 开启 TLS/SSL 协议,启用 HTTPS 服务。
  http2 on;        # 启用 HTTP/2.0 支持。
  ssl_certificate server.crt;  # 指定 SSL 证书文件路径。
  ssl_certificate_key server.key; # 指定 SSL 私钥文件路径。
}

资源推送指令,用于配置服务器主动向客户端推送资源。

http2_push 指令用于将请求与对原始请求的响应一起沿着发送(推送)到指定的 uri,使用相对路径也可使用变量,并且可在同一配置级别上指定多个 http2_push 指令,但自版本1.25.1起已过时,建议在头部字段中添加 Link 预加载提示。

Syntax: http2_push uri | off;
Default: http2_push off;
Context: http, server, location

# 示例
http2_push /static/css/main.css;

http2_push_preload 指令用于启用或禁用预加载推送,默认情况下是关闭的,启用后需在头部字段中添加 Link 预加载提示,以便浏览器知道哪些资源将被推送,同样自版本 1.25.1 起已过时。

Syntax: http2_push_preload on | off;
Default: http2_push_preload off;
Context: http, server, location

# 示例:若响应头含 Link: </star.css>; rel=preload,则star.css被推送。
http2_push_preload on;

请求接并发与流控制指令,用于配置 HTTP/2.0 连接并发和流控制相关参数。

http2_max_concurrent_pushes 指令用于限制连接中并发推送请求的最大数量,自版本1.25.1起已过时。

Syntax: http2_max_concurrent_pushes number;
Default: http2_max_concurrent_pushes 10;
Context: http, server

http2_max_concurrent_streams 指令用于设置连接中并发HTTP/2流的最大数量,自版本1.25.1起已过时。

Syntax: http2_max_concurrent_pushes number;
Default: http2_max_concurrent_pushes 10;
Context: http, server

http2_max_requests 指令用于设置一个HTTP/2连接可以处理的最大请求数(包括推送请求),超过此数量后,下一个客户端请求将导致连接关闭并需要建立新的连接,自版本1.25.1起已过时,建议使用 keepalive_requests 指令代替。

Syntax: http2_max_requests number;
Default: http2_max_requests 1000;
Context: http, server

http2_chunk_size 指令用于设置响应正文切片的最大块大小, 过低的值会导致更高的开销, 过高的值会由于HOL阻塞而损害优先级。

Syntax: http2_chunk_size size;
Default: http2_chunk_size 8k;
Context: http, server, location

缓冲区大小设置指令,用于配置 HTTP/2.0 连接缓冲区大小相关参数。

http2_body_preread_size 指令用于设置每个请求主体的缓冲区大小,默认情况下是 16k。

Syntax: http2_body_preread_size size;
Default: http2_body_preread_size 64k;
Context: http, server

http2_max_field_size 指令用于限制经过HPACK压缩的请求标头字段的最大大小,默认情况下是 4k。自版本1.19.7起已过时,建议使用 large_client_header_buffers 指令。

Syntax: http2_max_field_size size;
Default: http2_max_field_size 4k;
Context: http, server

http2_max_header_size 指令用于限制HPACK解压缩后整个请求标头列表的最大大小。对于大多数请求,默认限制应该足够了,自版本1.19.7起已过时,建议使用 large_client_header_buffers 指令。

Syntax: http2_max_header_size size;
Default: http2_max_header_size 16k;
Context: http, server

http2_recv_buffer_size 指令用于设置每个工作进程输入缓冲区的大小。

Syntax: http2_recv_buffer_size size;
Default: http2_recv_buffer_size 256k;
Context: http

超时控制指令,用于配置 HTTP/2.0 连接超时相关参数。

http2_idle_timeout 指令用于空闲多少时间后关闭连接,自版本1.19.7起已过时,建议使用 keepalive_timeout 指令代替。

Syntax: http2_idle_timeout time;
Default: http2_idle_timeout 3m;
Context: http, server

http2_recv_timeout 指令用于设置接收超时时间,自版本1.19.7起已过时,应该使用 client_header_timeout 指令。

Syntax: http2_recv_timeout time;
Default: http2_recv_timeout 30s;
Context: http, server

另外,该模块还提供了一个内置变量 $http2,可用于检测当前连接是否为 HTTP/2.0 连接,其变量标识符值为:

  • “h2” for HTTP/2 over TLS,
  • “h2c” for HTTP/2 over cleartext TCP, or an empty string otherwise.

实践演示

步骤 01.作者准备一些静态资源文件和自签证书【参考文章:Nginx | 核心知识150讲之SSL证书签发与HTTPS加密传输学习实践笔记】,以演示其 HTTP/2.0 资源推送功能。

$ cd /usr/local/nginx/html

$ tree .
.
├── video.html
├── img
│   └── bg.png
├── video
│   └── 202403192224.mp4
├── css
│   └── style.css
├── js
│   └── index.js
└── index.html


<!-- 其中 index.html 首页,内容如下 -->

tee index.html <<'EOF'
<HTML>

<HEAD>
<meta charset="UTF-8">
<title>测试HTTP2.0推送</title>
</HEAD>
<BODY>
<h1>测试HTTP2.0推送</h2>
<BODY>
</HTML>
EOF

<!-- 其中创建一个视频播放页面,如下所示: -->
tee video.html <<'EOF'
<video
id="myVideo"
class="responsive-video"
src="/videos/202403192224.mp4"
poster="/img/bg.jpg"
preload="metadata"
controls
playsinline
muted
loop
width="1280"
height="720"
crossorigin="anonymous"
data-setup='{}'>


<!-- 多格式源文件,确保浏览器兼容性 -->
<!-- <source src="/videos/sample.mp4" type="video/mp4">
  <source src="/videos/sample.webm" type="video/webm">
  <source src="/videos/sample.ogv" type="video/ogg">
   -->

<!-- 字幕/字幕轨道 -->
<!-- <track kind="subtitles" src="/videos/captions.vtt" srclang="zh" label="中文">
  <track kind="subtitles" src="/videos/captions-en.vtt" srclang="en" label="English">
  <track kind="chapters" src="/videos/chapters.vtt" srclang="zh">
   -->

<!-- 降级方案 -->
<p class="video-fallback">
    您的浏览器不支持 HTML5 视频。
    <a href="/videos/202403192224.mp4" download>下载视频</a>
</p>
</video>
EOF

步骤 02.配置 Nginx 启用 HTTP/2.0 支持,并开启资源推送功能,修改完毕后验证配置并重启 Nginx 服务。

tee /usr/local/nginx/conf.d/server.conf <<'EOF'
# 只在连接为 HTTP/2 且支持推送时执行推送
map $http2$push_allowed {
  default  "";
"h2"     "1";
}

server {
# 监听 443 端口,启用 TLS/SSL 协议
  listen 443 ssl;
# 虚拟主机服务器名称
  server_name server.weiyigeek.top;
  default_type text/html;

# 启用 HTTP/2 支持
  http2 on;

# 日志文件
  access_log /var/log/nginx/server.log main;
  error_log /var/log/nginx/server.err.log debug;

# SSL 证书文件
  ssl_certificate /usr/local/nginx/certs/server.crt;
# ssl_certificate_key /usr/local/nginx/certs/server.key;

# 加密的 SSL 证书密钥文件(根据需求选择)
  ssl_certificate_key /usr/local/nginx/certs/server_encrypted.key;
  ssl_password_file /usr/local/nginx/certs/ssl_password.txt;

# 支持的 SSL/TLS 协议版本
  ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;

# 支持的 SSL/TLS 加密套件
  ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE:ECDH:AES:HIGH:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DH:!DES:!MD5:!RC4;

# SSL 会话缓存
  ssl_session_cache shared:SSL:10m;
# SSL 会话超时时间
  ssl_session_timeout 10m;
# 优先使用服务器端支持的加密套件
  ssl_prefer_server_ciphers on;

# 强制使用 HTTPS 访问
  add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload" always;

# 根目录设置
  root /usr/local/nginx/html;
# 缺省文件索引页设置,即访问根目录时默认打开的文件名
  index index.html;

# 使用 Link 指定推送多个资源
  location / {
    # 推送 css 和 js 文件作为预加载资源
    add_header Link "</css/style.css>; as=style; rel=preload, </js/index.js>; as=script; rel=preload" always;

    # 缓存控制
    expires 1h;
    add_header Cache-Control "public, no-cache";
  }

# 仅当连接为 HTTP/2 且支持推送时才执行推送
  location = /video.html {
    if ($push_allowed) {
      #  推送 MP4 视频文件
      add_header Link "</css/style.css>; as=style; rel=preload, </videos/202403192224.mp4>; as=video; type=video/mp4; rel=preload" always;

      # 可选:推送视频封面图
      add_header Link "</img/bg.png>; as=image; rel=preload" always;

      # 缓存控制
      expires 1h;
      add_header Cache-Control "public, no-cache";
    }
  }

# 特别注意:使用 http2_push、http2_push_preload 指令推送资源已失效,Nginx 1.25.1 及以后已不支持这种方式。
  location /old { 
    http2_push /css/style.css;
    http2_push /res/202403192224.mp4;
  }
}
EOF

# 验证重载
nginx -t && nginx -s reload
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
nginx: [warn] the "http2_push" directive is obsolete, ignored in /usr/local/nginx/conf.d/server.conf:77
nginx: [warn] the "http2_push" directive is obsolete, ignored in /usr/local/nginx/conf.d/server.conf:78

温馨提示:Nginx 1.25.1 及以后版本已废弃 http2_push、http2_push_preload 等指令,不再支持资源推送功能,在配置文件中使用这些指令将会被忽略,一定要使用 add_header Link 方式来实现资源推送。

步骤 03.为了防止各位看友旧版本的 curl 工具不支持 HTTP/2.0 协议,所以这里我们使用 nghttp 命令行工具来测试 Nginx HTTP/2.0 协议,可通过 Github 或者通过包管理器安装,官网地址:https://nghttp2.org/

# 方式1.通过 Github 下载版本进行编译安装
# Ubuntu/Debian
sudo apt-get install g++ make binutils autoconf automake \
  autotools-dev libtool pkg-config zlib1g-dev libcunit1-dev \
  libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev \
  libc-ares-dev libjemalloc-dev libsystemd-dev cython python3-dev

# CentOS/RHEL
sudo yum install gcc gcc-c++ make cmake automake autoconf libtool \
  pkgconfig zlib-devel openssl-devel libxml2-devel libev-devel \
  jansson-devel c-ares-devel python3-devel  python3-pip

# 下载源码
wget https://github.com/nghttp2/nghttp2/releases/download/v1.68.0/nghttp2-1.68.0.tar.xz

# 解压
xz -k -d nghttp2-1.68.0.tar.xz
tar -xvf nghttp2-1.68.0.tar

# 构建
./configure --enable-app

# 编译
make -j$(nproc)

# 检查产物
ls  src/.libs/  # 有时临时文件在这里
deflatehd  h2load  inflatehd  nghttp  nghttpd  nghttpx
# 主要工具包括:
#   nghttp - HTTP/2 客户端
#   nghttpd - HTTP/2 服务器
#   h2load - 负载测试工具
#   nghttpx - 代理服务器

# 安装
sudo make install

# 更新动态链接库缓存
sudo ldconfig /usr/local/lib

# 方式2.通过包管理器安装(版本可能过旧)
# redhat 系
yum install nghttp2
# debian 系
apt install nghttp2


weiyigeek.top-nghttp2测速工具图

步骤 04.使用 nghttp 命令行工具测试 Nginx HTTP/2.0 支持情况,

# 访问主页路径
/usr/local/bin/nghttp -ans https://nghttp2.org
***** Statistics *****
Request timing:
  responseEnd: the  time  when  last  byte of  response  was  received
               relative to connectEnd
 requestStart: the time  just before  first byte  of request  was sent
               relative  to connectEnd.   If  '*' is  shown, this  was
               pushed by server.
      process: responseEnd - requestStart
         code: HTTP status code
         size: number  of  bytes  received as  response  body  without
               inflation.
          URI: request URI

see http://www.w3.org/TR/resource-timing/#processing-model

sorted by 'complete'

id  responseEnd requestStart  process code size request path
  1   +731.81ms        +73us 731.74ms  200   6K /
  3      +1.27s    +732.00ms 537.07ms  200   6K /javascripts/modernizr-2.0.js
  5      +1.34s    +732.01ms 612.92ms  200   8K /javascripts/octopress.js
  2      +1.34s *  +246.02ms    1.10s  200  38K /stylesheets/screen.css


# 访问 / 路径
/usr/local/bin/nghttp -anv --no-verify https://server.weiyigeek.top/

# 访问 /video.html 路径
/usr/local/bin/nghttp -anv --no-verify https://server.weiyigeek.top/video.html 

weiyigeek.top-使用 nghttp 命令行工具验证图

但经过作者测试,在访问验证 HTTP/2.0 自动推送时,建议通过主流的浏览器(Firefox、Google、Edge)进行访问 /video.html 路径时,可以更加直观的看到资源推送的效果。

weiyigeek.top-使用主流浏览器验证HTTP2.0推送图

温馨提示: 若 curl 版本够新支持--http2 参数也是可以进行检查 ALPN 协商,例如:

$ curl -V
curl 8.4.0 

# 查看详细的 HTTP/2 信息
curl -i --http2 https://server.weiyigeek.top/video.html -k
HTTP/2 200
server: nginx/1.29.0
date: Sat, 10 Jan 2026 15:20:55 GMT
content-type: text/html
content-length: 931
last-modified: Sat, 10 Jan 2026 04:51:37 GMT
etag: "6961dad9-3a3"
expires: Sat, 10 Jan 2026 16:20:55 GMT
cache-control: max-age=3600
link: </css/style.css>; as=style; rel=preload, </videos/202403192224.mp4>; as=video; type=video/mp4; rel=preload
link: </img/bg.png>; as=image; rel=preload
cache-control: public, no-cache
accept-ranges: bytes

步骤 05.查看 Nginx 访问日志,可以看到资源推送的效果,由下图可知即使 index.html 中未引入 css / js 文件也将主动推送,另外在 video.html 文件中未引入 css 以及 png 文件也是一并推送的。

weiyigeek.top-利用Nginx 访问日志查看HTTP2.0消息推送图

至此,本文详细介绍了 HTTP/2.0 协议,和 Nginx 中 ngx_http_v2_module 模块指令参数,以及如何开启 HTTP/2.0 支持,并演示了其资源推送功能。


阅读原文:原文链接


该文章在 2026/1/12 10:52:36 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved