HTTP3快来了,提前学习一下如何在Nginx中支持HTTP3.0/QUIC

HTTP3.0,也称作HTTP over QUIC。核心是QUIC(读音quick)协议,由Google在2015年提出的SPDY v3演化而来的新协议,传统的HTTP协议是基于传输层TCP的协议,而QUIC是基于传输层UDP上的协议,可以定义成:HTTP3.0基于UDP的安全可靠的HTTP2.0协议,主要有以下特性:

  • 基于UDP减少了TCP三次握手及TLS握手时间
  • 解决多路复用丢包时的线头阻塞问题
  • 优化重传策略
  • 流量控制
  • 连接迁移

关于HTTP3.0相关的详细解释,这里就不在多讲的,各位感兴趣的读者可以看下我之前的一篇文章《HTTP发展史(HTTP1.1,HTTPS,SPDY,HTTP2.0,QUIC,HTTP3.0)》,本文主要讲解一下如何在Nginx中开启HTTP3.0的支持。

方案选择

对于HTTP3.0,由于整个协议还是处于草案阶段,目前来说没有一个完整的标准,所以各大浏览器厂商还只是在开发者版本中才会支持,例如Chrome的金丝雀版本Chrome Canary,并且各个服务器厂商也是在持续跟进中,对于Nginx来说,支持HTTP3.0目前有两种方案可以选择:

  • 基于Cloudflare的分支版本Nginx:对于HTTP3.0/QUIC,Cloudflare始终走在了前列,借助于自家维护的开源项目quic,从Nginx中拉出了一个分支来开发,并编译出了对HTTP3.0支持的Nginx服务器。
  • Nginx官方Nginx-quic项目:今年6月10日,Nginx官博发布公告称已经在研发支持HTTP3.0/QUIC协议的工作,目前项目维护在nginx-quic,该项目和基于Cloudflare基于Nginx的分支并无关系,算是相对于正统的方案。

基于此,本文将会以部署nginx-quic的方式来让Nginx支持HTTP3.0/QUIC。

改造过程

我们最终的目的是得到nginx-quic版本的nginx可执行文件,需要经过一系列的安装和编译,期间可能会遇到很多问题,如果各位读者不想实际操作,可以直接用我编译好的版本nginx-quic.linux-x86_64.zip 传送门。

准备工作:

以centos7为例,下载nginx-quic源码传送门,下载完成之后,需要进行编译安装,由于nginx-quic依赖boringSSL,所以还需下载boringSSL源码传送门,然后同样需要编译安装boringSSL,执行这些操作之前,需要在linux上安装一些前置模块,通过yum来安装,执行以下命令:

sudo yum install build-essential mercurial psmisc lsb-release cmake golang libunwind-dev git libpcre3-dev zlib1g-dev
复制代码

什么是boringSSL:

对于Nginx来说,在编译时需要配置对于的SSL库,不管是HTTP3.0还是HTTP2.0,始终都要基于HTTPS,而加密算法这块主要有OpenSSL来提供,而BoringSSL是谷歌创建的OpenSSL分支,用于支持TLS1.3的UDP协议0-RTT数据传输的加密算法(可以理解成TLS1.3是标准协议,BoringSSL是实现工具),BoringSSL的一些特性会在合适的时机同步给OpenSSl。

编译安装boringSSL:

cd boringssl-master/
mkdir build
cd build
cmake ../
make
复制代码

执行之后,可以在build/crypto,和build/ssl下获得对应的文件,如下图:

注意编译安装boringSSL需要使用cmake3以上的版本。

编译安装nginx-quic:

cd nginx-quic/
./auto/configure --prefix=/root/nginx --with-http_ssl_module --with-http_v2_module --with-http_v3_module --with-cc-opt="-I../boringssl-master/include" --with-ld-opt="-L../boringssl-master/build/ssl -L../boringssl-master/build/crypto"
make
make install
复制代码

执行命令之后,会在/root/nginx目录下生成对应的nginx可执行文件,如下图:

其中,配置文件在conf/下,nginx命令在sbin/目录下。

修改配置文件,启动nginx:

vi /root/nginx/conf/nginx.conf
复制代码

添加http3配置:

server {listen 443 ssl http2;              # TCP listener for HTTP/2listen 443 http3 reuseport;  # UDP listener for QUIC+HTTP/3ssl_protocols       TLSv1.3; # QUIC requires TLS 1.3ssl_certificate     ssl/www.example.com.crt;ssl_certificate_key ssl/www.example.com.key;add_header Alt-Svc 'quic=":443"; h3-27=":443";h3-25=":443"; h3-T050=":443"; h3-Q050=":443";h3-Q049=":443";h3-Q048=":443"; h3-Q046=":443"; h3-Q043=":443"'; # Advertise that QUIC is available
}
复制代码

其中,要求使用TLSv1.3版本,并且当浏览器不支持http3时,可以选择http2。 另外,add_header Alt-Svc添加这个返回头不可缺少。

  • Alt-Svc 全称为“Alternative-Service”,直译为“备选服务”。该头部列举了当前站点备选的访问方式列表,让服务器可以告诉客户端 “看,我在这个主机的这个端口用这个协议提供相同的服务”。一般用于在提供 “QUIC” 等新兴协议支持的同时,实现向下兼容。参考MDN。

验证HTTP3生效:

由于目前浏览器对HTTP3.0/QUIC的支持性有限,可以通过http3check.net/来验证站点启用HTTP3是否成功,以我的站点为例:

坑点总结

整个过程看似很简单,但是真正配置过程中遇到了不少坑,前前后后加上搜索问题花了一天半的时间才真正解决,把这些问题记录下来,分享给大家。

开启UDP的443端口:

由于quic协议使用的是UDP的443端口,这个端口对于centos7来说是默认关闭的,可以采用下面命令开启:

firewall-cmd --zone=public --add-port=443/udp --permanent
复制代码

如果项目托管在阿里云上,需要更新ECS的安全组策略来对外开启对应的协议和端口,如下图:

TLS版本向下兼容:

由于使用了TLS 1.3,所以会修改对应加密算法,但是对于一些浏览器而言还不支持这么高的版本,尤其是对于苹果的Safari,所以,在配置nginx配置文件时,要多配置几个版本向下兼容,代码如下:

ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
复制代码

-Werror错误问题:

在编译nginx-quic时,有时会遇到如下错误:


cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \-o objs/src/os/unix/ngx_linux_sendfile_chain.o \src/os/unix/ngx_linux_sendfile_chain.c
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \-o objs/src/event/ngx_event_openssl.o \src/event/ngx_event_openssl.c
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \-o objs/src/event/ngx_event_openssl_stapling.o \src/event/ngx_event_openssl_stapling.c
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \-o objs/src/event/ngx_event_quic.o \src/event/ngx_event_quic.c
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \-o objs/src/event/ngx_event_quic_transport.o \src/event/ngx_event_quic_transport.c
src/event/ngx_event_quic_transport.c: In function ‘ngx_quic_create_stream’:
src/event/ngx_event_quic_transport.c:54:9: error: comparison is always true due to limited range of data type [-Werror=type-limits]: ((uint32_t) value) <= 16383 ? 2                                        \^
src/event/ngx_event_quic_transport.c:1299:15: note: in expansion of macro ‘ngx_quic_varint_len’len = ngx_quic_varint_len(sf->type);^
cc1: all warnings being treated as errors
make[1]: *** [objs/src/event/ngx_event_quic_transport.o] Error 1
make[1]: Leaving directory `/root/nginx-quic'
make: *** [build] Error 2
[root@iz2zehmi1ztqtx8tg6ca7gz nginx-quic]#
复制代码

解决办法是:

cd nginx-quic\objsvi Makefile复制代码

找到 CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include将-Werror参数去掉。

reuseport只需配置一次:

假如有多个域名需要开启http3,则reuseport建议只在根域名上配置,如果一个配置文件中出现多个reuseport,会报错,配置如下:

    server {listen 443 ssl http2;              # TCP listener for HTTP/2listen 443 http3 reuseport;  # UDP listener for QUIC+HTTP/3server_name  www.nihaoshijie.com.cn default_server;}server {listen 443 ssl http2;        # TCP listener for HTTP/2listen 443 http3;  # UDP listener for QUIC+HTTP/3server_name  app.nihaoshijie.com.cn;}
复制代码

编译安装时的性能问题:

如果编译安装时报类似下面的错误,可能是主机的内容不足,需要关闭一些运行的程序来往下进行。

...
c++: internal compiler error: Killed (program cc1plus)
复制代码

快开启你的HTTP3之旅吧,码字不易,如果本文对你有帮助,点赞支持一下~

关注下面的标签,发现更多相似文章

HTTP3

原文链接:https://juejin.im/post/5f0bb78fe51d4534a711efbf

HTTP3快来了,提前学习一下如何在Nginx中支持HTTP3.0/QUIC相关推荐

  1. 你们公司还没使用HTTP3?赶紧来补一补,学习一下如何在Nginx上配置HTTP3。

    你们公司还没使用HTTP3?赶紧来补一补,学习一下如何在Nginx上配置HTTP3. NGINX最新版本,已提供对 QUIC 和 HTTP/3的支持,本文介绍一下如何安装与配置 很高兴能在一个特殊的开 ...

  2. 在Nginx中支持HTTP3.0/QUIC

    在Nginx中支持HTTP3.0/QUIC HTTP3.0,也称作HTTP over QUIC.核心是QUIC(读音quick)协议,由Google在2015年提出的SPDY v3演化而来的新协议,传 ...

  3. 使用keras进行深度学习_如何在Keras中通过深度学习对蝴蝶进行分类

    使用keras进行深度学习 A while ago I read an interesting blog post on the website of the Dutch organization V ...

  4. 四十二、开始Vuex的学习:如何在Vue中使用Vuex

    @Author:Runsen @Date:2020/7/12 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏 ...

  5. matlab学习笔记:如何在matlab中如何自定义函数和匿名函数

    matlab在一定程度上也能完成编程工作,其程序语言是由C++演变过来的,但却又不尽相同.matlab的程序语言在拓展性上没有C++齐全,但也足够应付一些简单的程序,而且比C++更易于学习. inpu ...

  6. PS学习记录111111--如何在PS中创建一个干净的网页布局

    作为编码者,美工基础是偏弱的.我们可以参考一些成熟的网页PS教程,提高自身的设计能力.套用一句话,"熟读唐诗三百首,不会作诗也会吟". 1111111111111111111111 ...

  7. Silverlight学习之——如何在 Silverlight 中使用 Deep Zoom

    Deep Zoom 使您能够快速缩放和平移高分辨率图像.Deep Zoom 可以使用多分辨率图像来实现上述功能. 下面演示如何创建使用 Deep Zoom 的非常简单的 Silverlight 应用程 ...

  8. 快速学习:如何在Java中以编程方式将PNG或JPG图像转换为PSD?

    JPG和PNG图像是一些最常用的光栅图像格式.有时可以根据需要将JPG或PNG图像转换为PSD文件格式.当要将不同的图层组合到一个文件中时,这可能会很有用.本文将介绍一下更多详细信息: 使用Java以 ...

  9. 该如何才能更快且有效的学习?

    昨天花了一天的时间,整理了如何一天学会Go语言,写完后,我把我自己当成一个从没接触过Go语言的学习者,看了几遍,发现对一个没学过Go语言的人来说,根本没有任何帮助 而对于已经学习过Go语言的读者大人们 ...

最新文章

  1. 4.4. Config file
  2. Winform中使用用户控件实现带行数和标尺的RichTextBox(附代码下载)
  3. python pip配置镜像源:douban不能下载aliyun可以下载
  4. python基础知识05-控制流程
  5. SAP CRM WebClient UI上UI标签文本的显示逻辑
  6. 【DP】Mod Mod Mod(CF889E)
  7. 用户需求、己、竞争对手的关系
  8. 怎样写出简洁的css代码??★★★★
  9. 博客园添加鼠标粒子吸附特效
  10. MySql 随机读取多行数据并显示
  11. 使用Canvas基于手势可以使树秋千
  12. 独具匠心的好书:评《构建高性能Web站点》
  13. mysql临时表多线程时能用吗_学会使用临时表优化,切记不要乱用临时表(记录一)...
  14. LPC11XX驱动LCD1602程序
  15. c语言平方根求和用sqrt函数,sqrt函数 Excel怎么使用平方根函数SQRT
  16. animator 控制移动_Unity UGUI通过摇杆控制角色移动
  17. 计算机密码无法输完整,笔记本电脑键盘失灵无法输入密码怎么解决
  18. linux版高德导航软件下载,高德导航2017
  19. 有效的数据治理,元数据该怎么管?
  20. 高通SDM845平台Sensor学习——3.SLPI(Physical Sensor)

热门文章

  1. magento 输出关联产品
  2. Ubuntu安装VMware Workstation详解
  3. NSURLConnection 下载数据 -- IOS(实例)
  4. Chrome浏览器获取XPATH的方法----通过开发者工具获取
  5. git-文本内容的回退-缓冲区退到工作区-工作区改动后改为改动前
  6. 爬虫-12-发送带参数的请求
  7. django-解决-修改过的模型类不能被正常迁移的解决办法
  8. linux-2-wc-od-du-df-文件目录磁盘使用情况查看
  9. jquery-属性操作
  10. laravel 关联关系之多态关联