
前置要求以及 HTTP/3.0 是什么
HTTP/3.0 是什么
HTTP/3 是 HTTP 协议的最新版本,于 2022 年由 Google 正式发布。HTTP/3 基于 QUIC 的新型传输协议之上(实际上就是 UDP),而不是像之前的 HTTP/1 和 HTTP/2 那样使用 TCP。这带来了几个重要的改进:
- 低延迟: 更快的连接建立在 HTTP/1 和 HTTP/2 中,每次建立新的连接都需要经过 TCP 的三次握手,然后再进行 TLS 握手。这个过程会产生显著的延迟。但在 HTTP/3 中,QUIC 协议握手阶段就集成了 TLS 的功能。所以建立一个安全连接只需要一次往返,大大减少了初始连接时间。这对于那些需要频繁建立新连接的应用,如移动网络,尤其有利。
- 多路复用,防止阻塞: 改进的多路复用 HTTP/2 引入了多路复用,允许在单个连接上并行发送多个请求。但它仍然容易受到 " 队头阻塞 " 问题的影响: 如果一个请求被阻塞,那么同一条连接上的所有其他请求也会被阻塞。HTTP/3 中的 QUIC 协议通过使用 UDP 解决了这个问题。UDP 是无连接的,所以每个请求是独立的,不会影响其他请求。这意味着即使一个请求遇到问题,其他请求仍然可以继续发送,从而提高了整体性能。
- 对移动连接的优化: 更好的移动网络性能在移动网络下,网络条件往往不稳定,经常会发生连接中断。当这种情况发生时,基于 TCP 的 HTTP/1 和 HTTP/2 通常需要重新建立连接,这会导致显著的延迟。但 HTTP/3 的 QUIC 协议有一种叫做 " 连接迁移 " 的功能。当你的移动设备在不同的网络之间切换时(例如,从 Wi-Fi 切换到蜂窝网络),QUIC 可以维持连接,避免了重新连接的开销。
- 安全性: 更强的安全性 HTTP/3 默认使用 TLS 1.3,这是迄今为止最安全的 TLS 版本。而在 HTTP/1 和早期的 HTTP/2 中,旧版本的 TLS 仍然普遍存在。此外,QUIC 有一些内置的安全措施,如加密数据包的序列号,有助于防止一些攻击。
前置要求
- nginx 版本应该大于 1.25.0
- 不能使用官方分支的 nginx 版本,所有如果使用的是 apt 包安装的 nginx 需要先预编译
- 不用 事先删除服务器中本身的 nginx(如果已经安装好了的话)
- 以下教程适用于 Debian/Ubuntu 发行版
编译
第一步: 安装编译所需要的依赖项
sudo apt install build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev libgd-dev libxml2 libxml2-dev uuid-dev libxslt1-dev libgeoip-dev libgoogle-perftools-dev libperl-dev
第二步: 下载 nginx 源码
wget https://nginx.org/download/nginx-1.27.3.tar.gz
tar -zxvf nginx-1.27.3.tar.gz
cd nginx-1.27.3
nginx 当前最新版为 1.27.3,理论上 1.25.0 以后的版本都可以,编译时请选择当时最稳定的版本
第三步: 编译
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --user=nginx --group=nginx --build=Debian --builddir=nginx-1.27.3 --with-select_module --with-poll_module --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_v3_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module=dynamic --with-stream_ssl_preread_module
make
make install
里面很多模块都有用,占用也不多,最好全部保留,以后就不用再次编译了
第四步: 移除旧的 Nginx,安装新 Nginx
sudo systemctl stop nginx
sudo mv /usr/sbin/nginx /usr/sbin/nginx.old
sudo cp objs/nginx /usr/sbin/nginx
注意最后一行将当前目录的 nginx 二进制文件转移到 /usr/sbin/nginx,有可能编译好的二进制文件并不在 ./objs 中,而是在其他位置,需要自行修改。
第五步: 启动 Nginx
sudo systemctl start nginx
此时,nginx 应该已经可以支持 HTTP/3 了,具体可以通过
nginx -V 2>&1 | grep -o with-http_v3_module
如果返回了 with-http_v3_module 则说明安装成功
HTTP/3.0 配置模板
server {
listen 443 ssl;
listen 443 quic; # http3
listen [::]:443 ssl;
listen [::]:443 quic; # http3
http2 on;
http3 on; #http3
add_header alt-svc 'h3=":443"; ma=86400'; #http3
server_name example.com; # 更改为需要反代的网址
# 使用 certbot 自动管理证书
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# 处理请求
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_pass http://localhost:8080 # 改为反代后端;
client_max_body_size 1024m;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
# 保持连接状态
proxy_http_version 1.1;
proxy_set_header Connection "";
# 日志记录
access_log /var/log/nginx/example.com_access.log;
error_log /var/log/nginx/example.com_error.log;
}
}
# HTTP 重定向到 HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com;
# 将 HTTP 请求重定向到 HTTPS
if ($host = example.com) {return 301 https://$host$request_uri;}
return 404; # 其他请求返回 404
}
正文完