对比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/2
listen 443 quic reuseport; # UDP 监听 443,支持 HTTP/3
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
# QUIC/HTTP3-specific TLS settings
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
# HTTP/3 settings
ssl_early_data on;
add_header Alt-Svc 'h3=":443"'; # Advertise that HTTP/3 is available
add_header QUIC-Status $quic;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}
nginx dockerfile
FROM ubuntu:22.04
ENV 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.04
ENV DEBIAN_FRONTEND=noninteractive
ENV PREFIX=/usr/local
RUN 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