全站已经启用HTTP3 + QUIC + Brotli

HTTP/3 的基础即谷歌多年探索的基于 UDP 的 QUIC 协议。与 TCP 相比,使用 UDP 可以提供更大的灵活性,并且可以使 QUIC 完全于用户空间中实现——对协议实现的更新不像 TCP 那样需要绑定到操作系统更新。使用 QUIC,可以简单地将 HTTP 级别的流映射到 QUIC 流的顶部,从而继承 HTTP/2 的所有优点,而不会产生队头阻塞。HTTP/3 虽仍处于草案状态,但很多用户已经跃跃欲试。

最近看上去HTTP/3协议,但是国内的CDN服务商基本不支持,又拍云虽然支持HTTP/3,但是不支持QUIC,如果开启了HTTP/3还有要经过CDN回源,那速度就不够快了。

为了追求极致,所以思考了一番之后,决定自建HTTP3 + QUIC 服务。

优势

  • HTTP/3 利用 QUIC 加速 HTTP 请求,QUIC 提供比 TCP 和 TLS 更高的加密和性能
  • QUIC 是一种默认加密的新传输协议,旨在加快 HTTP 传输速度以及使其更加安全
  • HTTP/3 基于 UDP,如果数据包丢失,只会中断一个流,而不会中断所有流,提高了同时获取多个对象的性能
  • 支持 0-RTT,消除服务器的 TLS 确认,使后续连接的启动速度更快

HTTP/2 多路复用 2 个请求。响应被分解为多个数据包,一旦一个数据包丢失了,两个请求都被阻止。

img

HTTP/3 复用 2 个请求。虽然浅色的数据包丢失了,但是深色的数据包传输得很好。

img

在相同丢包率的条件下,HTTP/3 和 HTTP/2 性能测试对比如下

测试环境:服务端(HTTP/3 with cubic & HTTP/2 with bbr)、客户端(cubic)

img

img

前言

我可能不是第一个用HTTP/3协议的网站,但我一定是第一个在宝塔上启用HTTP3支持的网站。

基本踩到的坑都踩完了,可以记录一下。

由于从零开始nginx编译HTTP/3支持的文章很多,所以本文默认使用宝塔环境,Ubuntu20.04系统。

开始

正常安装宝塔,在Nginx版本选择的时候注意选择1.16版本,选择编译安装,因为本文是采用的CloudFlare Quiche的patch方案,官方说Nginx1.16版本最为稳定,其他版本可能会有问题,理论上其他版本也能够支持,但是没测试,欢迎测试后给我反馈。

宝塔默认的编译完成后,接下来我们就需要给他增加HTTP/3扩展了。

由于Nginx默认没有HTTP/3支持,所以我们需要通过CloudFlare Quiche的patch方案给Nginx打上补丁。

我们首先在切换到宝塔源码的目录/www/server/nginx/src然后执行

#受网络原因可能超时,请自行解决
git clone https://github.com/cloudflare/quiche
cd quiche
git submodule update --init --recursive

#执行patch程序,注意执行路径和patch路径
cd /www/server/nginx/src
patch -p01 < ./quiche/extras/nginx/nginx-1.16.patch

第一个坑就是第三条命令git submodule update --init --recursive不能省略!!因为deps目录链接了boringssl项目地址,如果不执行这条命令子模块就不完整,编译会报错!

安装相关依赖

先执行apt update && apt upgrade再说

很多依赖,需要最新版本,因为apt包上的版本太老了,可能不支持,为了保险起见,全部编译最新版本。

CMAKE

# 前往 https://cmake.org/files/ 选择最新版本下载
wget https://cmake.org/files/v3.21/cmake-3.21.0-rc2.tar.gz
tar xvzf cmake-3.21.0-rc2.tar.gz
cd cmake-3.21.0-rc2/
./bootstrap
make
make install

手动编译过程中缺什么就装什么,比如makegcc

PERL

# 前往 https://www.cpan.org/src/ 选择最新版本下载
wget https://www.cpan.org/src/5.0/perl-5.34.0.tar.gz
tar -xzf perl-5.34.0.tar.gz

# 编译安装
cd perl-5.34.0
./Configure -des -Dprefix=/usr/mysf
make
make test
make install

# 建立新的软链接
mv /usr/bin/perl /usr/bin/perl.bak
ln -s /usr/mysf/bin/perl /usr/bin/perl

# 检查是否安装成功
perl -v

Rust

Rust在Ubuntu中为rustc,官网提供了一键安装脚本,先检查系统有没有安装rust,如果安装了请执行rustc -V检测版本,低于1.39请先卸载再运行以下脚本。

# 为了支持 quiche,Rust 需要至少 1.39 版本
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Go

你没有看错,还需要go支持,这里直接apt安装就行。

sudo apt install golang-go

但是这里有一个坑,国内的网络环境,你需要给go设置代理,不然后面编译的时候会超时报错!

# 设置代理
go env -w GO111MODULE=on
go env -w  GOPROXY=https://goproxy.cn,direct

Brotli(可选)

既然都上HTTP3了,那何不更快一点呢?

git clone https://github.com/google/ngx_brotli
cd ngx_brotli
git submodule update --init

编译

首先执行nginx -V会出现一长串配置,复制下来。

configure arguments: --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module

然后我们稍做修改,将原本的--with-openssl=/www/server/nginx/src/openssl去掉

再加上新的编译参数,注意根据实际情况替换路径

--with-http_v3_module --with-openssl=/www/server/nginx/src/quiche/deps/boringssl --with-quiche=/www/server/nginx/src/quiche  --add-module=/www/server/nginx/src/ngx_brotli

所以去/www/server/nginx/src/目录下执行以下命令

./configure --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module --with-http_v3_module --with-openssl=/www/server/nginx/src/quiche/deps/boringssl --with-quiche=/www/server/nginx/src/quiche  --add-module=/www/server/nginx/src/ngx_brotli

不出意外,一会就行了,如果有报错就检查前面几步,或者百度,缺什么环境就装什么环境。

然后开始手动编译make就行了,千万不要make intsall

make

一样的,不出意外,一会就行了,如果有报错就检查前面几步,或者百度,缺什么环境就装什么环境。

接着执行

mv /www/server/nginx/sbin/nginx /www/server/nginx/sbin/nginx.old
cp objs/nginx /www/server/nginx/sbin/nginx
make upgrade

如果没有报错,恭喜你就成功了。

享受HTTP/3

HTTP/3是基于HTTPS的,所以请务必先配置好SSL证书!

启用HTTP3支持

进入网站管理,修改配置文件,加入这两行

listen 443 quic reuseport;

add_header alt-svc 'h3=":443"; ma=86400;quic=":443"; ma=2592000; v="46,43", h3-Q050=":443"; ma=2592000, h3-Q049=":443"; ma=2592000, h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000, h3-Q043=":443"; ma=2592000, h3-23=":443"; ma=2592000';

开启0-RTT

终端下运行

openssl rand 80 > /www/server/nginx/ticket.key

然后在配置文件中加入以下两行。

ssl_early_data on;
ssl_session_ticket_key /www/server/nginx/ticket.key;

开启Brotli压缩

Brotli是一种全新的数据格式,可以提供比Zopfli高20-26%的压缩比。据谷歌研究,Brotli压缩速度同zlib的Deflate实现大致相同,而在Canterbury语料库上的压缩密度比LZMA和bzip2略大。

在配置文件中加入以下配置开启Brotli,前提是前面选择编译了Brotli模块。

brotli on;
brotli_comp_level 6;
brotli_buffers 16 8k;
brotli_min_length 20;
brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;

测试HTTP/3

https://gf.dev/http3-test

Enjoy it

image-20210915173945726

引用

1、[又拍云]: https://www.upyun.com/http3 "HTTP/3 重磅来袭"
2、[雨浣潇湘]: https://www.thjiang.com/2019/11/21/%E4%B8%8D%E6%AD%A2%E4%BA%8E%E7%A7%92%E5%BC%80%20%E2%80%94%E2%80%94%20%E5%9C%A8-Nginx-%E4%B8%AD%E5%BC%80%E5%90%AF-HTTP3-QUIC%E3%80%81TLS1-3%E3%80%81Brotli/ "不止于秒开 —— 在 Nginx 中开启 HTTP3/QUIC、TLS1.3、Brotli"