相比于 HTTP/2 及之前的 HTTP 版本,基于 QUIC (Quick UDP Internet Connections) 协议的 HTTP/3 实现了更低延迟、更好的网络适应性和增强的安全性。启用 Nginx 对 HTTP/3 的支持可以提升性能和用户体验,具体优点如下:

  1. 更低延迟:QUIC 的 0-RTT 和 1-RTT 握手机制减少了连接建立时间和重传时间,从而加快页面加载速度。
  2. 多路复用:HTTP/3 允许单个连接上并发多个请求,通过 UDP 协议实现,相比 TCP 有更好的恢复能力和减少阻塞的效果。
  3. 快速恢复:QUIC 使用定制的拥塞控制算法,能更快恢复丢包,提高传输效率。
  4. 增强安全性:QUIC 作为应用层加密协议,提供端到端加密,保护数据安全。
  5. 更好网络适应性:QUIC 支持在不中断会话的情况下更换IP地址或端口,优化了移动设备在网络切换时的表现。

要启用 Nginx 的 QUIC 支持,需在编译时加入 OpenSSL 或 BoringSSL,并在配置文件中激活 QUIC。自行编译较为复杂,需要手动编写服务脚本且升级不便。相比之下,使用预编译版本更为便捷。要启用 Nginx 的 QUIC 支持,需在编译时集成 OpenSSL 或 BoringSSL。手动编译较为复杂,使用预编译版本则更加便捷。

以下以 Rocky Linux 9.4 为例,展示如何使用 Nginx 的官方预编译版本。

安装 Nginx (Rocky Linux 9)

要添加安装源,请创建一个名为 /etc/yum.repos.d/nginx.repo 的文件,并包含以下内容:

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

接着执行以下命令:

# 更新源
dnf update
# 安装 nginx
dnf install nginx

修改配置文件,启用 HTTP/3

编辑 /etc/nginx/nginx.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    server_tokens          off;
    charset                utf-8;
    sendfile               on;
    tcp_nopush             on;
    tcp_nodelay            on;
    log_not_found          off;
    types_hash_max_size    2048;
    types_hash_bucket_size 64;
    client_max_body_size   16M;
    keepalive_timeout  65;

    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    # gzip
    gzip              on;
    gzip_min_length   1k;
    gzip_vary         on;
    gzip_proxied      any;
    gzip_comp_level   5;
    gzip_types        text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;

    # SSL
    ssl_session_timeout    1d;
    ssl_session_cache      shared:SSL:10m;
    ssl_session_tickets    off;

    # Diffie-Hellman parameter for DHE ciphersuites
    # 用于前向保密,生成 dhparam.pem 命令如下
    # openssl dhparam -out /etc/nginx/dhparam.pem 2048
    ssl_dhparam            /etc/nginx/dhparam.pem;

    # Mozilla Intermediate configuration
    ssl_protocols         TLSv1.3 TLSv1.2;
    ssl_ciphers            HIGH:!aNULL:!MD5;

    # OCSP Stapling
    ssl_stapling           off;
    ssl_stapling_verify    off;
    # DNS 按需配置
    resolver               1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] valid=60s;
    resolver_timeout       2s;

    include /etc/nginx/http.d/*.conf;
}

编辑 /etc/nginx/http.d/example.com.conf

server {
    listen [::]:443 quic;
    listen 443 quic;
    listen [::]:443 ssl;
    listen 443 ssl;
    listen [::]:80;
    listen 80;

    http2 on;

    # enable http3
    http3 on;
    add_header Alt-Svc 'h3=":443"; ma=86400';
    # enable 0-RTT
    ssl_early_data on;

    # openssl rand 80 > /srv/ssl/ssl_session_ticket_key.key
    ssl_session_ticket_key /srv/ssl/ssl_session_ticket_key.key;

    server_name www.example.com example.com;

    # redirect non-www to www, http to https
    if ($http_host = "example.com") {
      return 301 https://www.example.com$request_uri;
    }
    if ($scheme = "http" ) {
      return 301 https://www.example.com$request_uri;
    }

    # root
    root   /srv/web/example.com/www_public;
    index  index.html;
    #try_files $uri $uri/ /index.html;

    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # SSL
    ssl_certificate     /srv/ssl/example.com_fullchain.cer;
    ssl_certificate_key /srv/ssl/example.com.key;

    # logging
    access_log          /var/log/nginx/example.com.access.log combined buffer=512k flush=1m;
    error_log           /var/log/nginx/example.com.error.log warn;
}

HTTP/3 的关键配置

# 监听 quic 协议的 443 端口
listen [::]:443 quic;
listen 443 quic;

# 启用 http/3
http3 on;

# 添加响应头,告诉客户端 http/3 使用的端口;缓存有效时间为 24h
add_header Alt-Svc 'h3=":443"; ma=86400';

# 启用 0-RTT
ssl_early_data on;

运行 Nginx

# 测试配置文件
nginx -t
# 设置开机自动启动
systemctl enable nginx
# 运行 nginx
systemctl start nginx

预编译软件包及参考文档