Nginx支持HTTP2/HTTP3的并用CURL测试
对比HTTP2和HTTP3
HTTP/3 相比 HTTP/2 的主要优势:
项目 | HTTP/2 | HTTP/3 |
---|---|---|
传输层 | 基于 TCP(+ TLS) | 基于 QUIC(内置 TLS) |
建立连接速度 | 慢,至少 2~3 次握手(TCP + TLS) | 快,只需 1 次握手(QUIC) |
丢包影响 | 全连接阻塞(队头阻塞) | 流量独立,单流丢包不影响其它流 |
移动网络切换(IP变更) | 连接断掉,要重新建立 | 支持连接迁移,快速恢复 |
加密机制 | TLS 1.2 / 1.3 (分层叠加) | QUIC 原生内建 TLS 1.3 |
传输可靠性 | 可靠传输(但因 TCP 层次受限) | 可靠且高效,灵活可扩展 |
多路复用效率 | 好,但受 TCP 队头阻塞限制 | 真正的多路复用,不互相影响 |
适配性 | 成熟,广泛部署 | 新兴技术,主流浏览器已支持,但服务器普及率较低 |
具体讲解:
1. 连接速度更快(0-RTT、1-RTT)
-
HTTP/2 要经历 TCP 三次握手 + TLS 握手,至少 2-3 次来回。
-
HTTP/3 使用 QUIC,可以 一次握手建立加密连接(甚至 0-RTT 重连)。
-
移动端体验大幅提升,尤其在高延迟、弱网环境下。
2. 消除 TCP 队头阻塞问题
-
HTTP/2 是在 TCP 上的多路复用,但 TCP 只保证顺序交付,如果一个包丢了,全局都会卡。
-
HTTP/3 的 QUIC 是流级别,单个流丢包只影响自己,不会阻塞其他请求,网页元素(图片、JS、CSS)能并行快速加载。
3. 连接迁移(Connection Migration)
-
移动网络(比如从 Wi-Fi 切换到 5G)时,TCP连接会断,应用需要重新建立。
-
QUIC 支持基于 连接ID 迁移,只要 IP 地址改变,不需要重建连接,延续之前会话,非常适合移动端。
4. 原生加密和灵活升级
-
QUIC 默认强制加密(TLS 1.3),安全性高。
-
QUIC 协议在应用层(UDP上实现),可以更快推新版本,不像 TCP/HTTP2 那样升级麻烦。
5. 拥塞控制更先进
-
QUIC 自带高级拥塞控制(类似 TCP Cubic、BBR等),而且因为是用户空间协议,更好调优和创新。
Nginx支持HTTP2和HTTP3
# Nginx主配置开启 QUIC
events {worker_connections 1024;
}http {include mime.types;default_type application/octet-stream;server {listen 443 ssl http2; # TCP 监听 443,支持 HTTP/2listen 443 quic reuseport; # UDP 监听 443,支持 HTTP/3ssl_certificate /etc/nginx/certs/fullchain.pem;ssl_certificate_key /etc/nginx/certs/privkey.pem;# QUIC/HTTP3-specific TLS settingsssl_protocols TLSv1.3;ssl_prefer_server_ciphers off;ssl_session_timeout 1d;ssl_session_cache shared:SSL:50m;# HTTP/3 settingsssl_early_data on;add_header Alt-Svc 'h3=":443"'; # Advertise that HTTP/3 is availableadd_header QUIC-Status $quic;location / {root /usr/share/nginx/html;index index.html index.htm;}}
}
nginx dockerfile
FROM ubuntu:22.04ENV DEBIAN_FRONTEND=noninteractive
ENV PREFIX=/usr/local# 安装基础依赖
RUN apt-get update && apt-get install -y \git gcc g++ make cmake automake autoconf \libtool pkg-config \zlib1g-dev libpcre3-dev \libssl-dev curl wget mercurial \libev-dev libevent-dev ca-certificates# 下载 quictls (带QUIC支持的 OpenSSL)
WORKDIR /tmp
RUN git clone --depth 1 -b OpenSSL_1_1_1w+quic https://github.com/quictls/openssl.git && \cd openssl && \./config --prefix=$PREFIX && \make -j$(nproc) && make install_sw# 下载 nginx-quic 源码
WORKDIR /tmp
RUN hg clone -b quic https://hg.nginx.org/nginx-quic# 编译 nginx-quic
WORKDIR /tmp/nginx-quic
RUN ./auto/configure \--prefix=$PREFIX/nginx \--with-http_v3_module \--with-http_ssl_module \--with-openssl=/tmp/openssl \--with-cc-opt="-O2" \--with-ld-opt="-Wl,-rpath,$PREFIX/lib" && \make -j$(nproc) && make install# 复制默认 nginx.conf
COPY nginx.conf /usr/local/nginx/conf/nginx.conf# 开放 443端口 (TCP+UDP)
EXPOSE 443/tcp
EXPOSE 443/udp# 容器入口
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
CURL测试工具
Dockerfile
FROM ubuntu:22.04ENV DEBIAN_FRONTEND=noninteractive
ENV PREFIX=/usr/localRUN apt-get update && apt-get install -y \build-essential \autoconf \automake \libtool \pkg-config \git \ca-certificates \wget \curl \libssl-dev \libev-dev \libevent-dev \zlib1g-dev \libpsl-dev# 安装 quictls (带 QUIC 支持的 OpenSSL)
WORKDIR /tmp
RUN git clone --depth 1 -b OpenSSL_1_1_1u+quic https://github.com/quictls/openssl.git && \cd openssl && \./config --prefix=$PREFIX --openssldir=$PREFIX && \make -j$(nproc) && make install# 安装 nghttp3
WORKDIR /tmp
RUN git clone https://github.com/ngtcp2/nghttp3.git && \cd nghttp3 && \git submodule update --init --recursive && \autoreconf -i && \./configure --prefix=$PREFIX --enable-lib-only && \make -j$(nproc) && make install# 安装 ngtcp2
WORKDIR /tmp
RUN git clone https://github.com/ngtcp2/ngtcp2.git && \cd ngtcp2 && \git submodule update --init --recursive && \autoreconf -i && \./configure --prefix=$PREFIX \--with-openssl=$PREFIX \--with-libnghttp3=$PREFIX \--enable-lib-only \PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig && \make -j$(nproc) && make install# 安装 nghttp2 (支持 HTTP/2)
WORKDIR /tmp
RUN git clone --recursive https://github.com/nghttp2/nghttp2.git && \cd nghttp2 && \autoreconf -i && \./configure --prefix=$PREFIX && \make -j$(nproc) && make install# 安装 curl (支持 HTTP/2 和 HTTP/3)
WORKDIR /tmp
RUN git clone https://github.com/curl/curl.git && \cd curl && \./buildconf && \./configure --prefix=$PREFIX \--with-ssl=$PREFIX \--with-nghttp2=$PREFIX \--with-ngtcp2=$PREFIX \--with-nghttp3=$PREFIX \--enable-alt-svc \--enable-http3 \--enable-http2 && \make -j$(nproc) && make install && ldconfig# 测试 curl
RUN curl --version# 容器入口
ENTRYPOINT [ "curl" ]
测试脚本
# 测试http2
docker run -it --rm curl-http3 --http2 -I https://www.1pay.finance# 若支持http2:输出的第一行 HTTP/2 200 # 测试http3
docker run -it --rm curl-http3 --http3 -I https://www.cloudflare.com# 若支持htt3:输出的第一行 HTTP/3 200