Web服务器快速启用QUIC协议

阅读:1007 2019-03-19 15:01:17 来源:新网

quic是quickudpinternetconnections的缩写,谷歌出品的传输协议,使用udp替换tcp来支持http通信。udp本身不是可靠传输,通过在其上添加流控、校验等功能,quic可以实现可靠传输,而且相比于tcp,它的流控功能在用户空间而不在内核空间,那么使用者就不受限于cubic或是bbr,而是可以自由选择,甚至根据应用场景自由调整优化。

quic为现有tcp+https+http2组合存在的诸多问题提供了解决方案:

最新版的chrome浏览器默认启用quic协议,只要后端服务器支持,chrome就会使用quic协议。现在谷歌自家的大部分网站都使用了quic协议。

不改变现有web服务架构,我们可以通过在内网添加一层反向代理,快速启用quic协议。这样,对于支持quic的客户端,使用quic协议改善外网通信,对于不支持quic的客户端,依旧沿用tcp通信,而且就算这个反向代理挂掉了,chrome浏览器还可以切回tcp通信,没有增加服务中断风险。

既然谷歌自家的网站已经启用了quic,我们可以访问试试看。怎么知道打开的网站是否走了quic协议呢,我们可以通过wireshark抓包验证,但还有更方便的方法,直接用chrome提供的工具,主要有三种方法:

开发者工具security选项卡

用chrome浏览器打开谷歌官网www.google.com.hk,按f12打开开发者工具,切换到security选项卡,刷新网页后选择左侧一个源站,可以看到它使用的协议:

chrome插件:http/2andspdyindicator

从chrome应用商店搜索插件名字可以下载,它用不同颜色标识当前网站使用的是http(灰色),http2(蓝色)或者quic(绿色)

网络调试页chrome://net-internals

chrome还提供一个url用于调试网络状态,在浏览器中访问chrome://net-internals/地址,或者点击上述插件的小图标即可进入。这里提供了非常丰富的监控和调试功能,我们重点需要关注quic页面和alt-svc页面。

点击左栏的quic可以查看浏览器quic的版本配置以及quic会话。

点击左栏的alt-svc可以查看站点quic的端口、超时等情况。本页面的一个示例如下表:

|--------------server-------------------|alternativeservice-------------||------------------------------------------|----------------------------------------||`https://client4.google.com`|quic:443,expires2018-04-1816:54:41||`https://zabbix.test.com`|quic:443,expires2018-03-2016:53:30(broken)|

可以看到client4.google.com这个域名启用了quic协议,在udp443端口,后面是缓存超时。特别需要注意的是,zabbix.test.com这个地址,它的最后有个(broken),意思是说虽然这个网站宣称自己支持quic协议,即有响应头alt-svc:quic:443,但是浏览器发出的quic请求未得到响应。这种情况有可能是防火墙屏蔽了udp443端口,也可能是后端的quic服务挂了。

chrome浏览器初次发出quic请求会使用的赛跑的方式,同时发出tcp和quic的请求,那个先返回就用哪个,确认quic服务可用之后,后续请求直接使用quic协议。但是,如果发现quic通道不可用了,它就把它标记为(broken),切回tcp连接。

chromium

quic是谷歌的,chromium中的quic实现算是官方实现,保证quic版本最新,但整个项目代码量太大,网络模块依赖较多,又使用了自己的一套编译工具,如果自己从中剥离quic协议栈也比较麻烦。

chromium提供的c++接口很底层,需要自己实现会话、连接和流的管理,反向代理接收quic请求之后,需要构造urlrequest发往后端。要实现这些功能,还要先了解chromium的线程、消息循环、智能指针等一系列基础构件的使用方法,比较复杂,好在网上能找到一个样例。这是一个尚在审核的提交,将来有望合入chromium主分支,能让用户快速启用quic尝鲜试用。

proto-quic

从chromium剥离的一个quic协议部分,但是其github主页已宣布不再支持,仅作实验使用。

goquic

goquic封装了libquic的go语言封装,而libquic也是从chromium剥离的,好几年不维护了,仅支持到quic36,goquic提供一个反向代理,测试发现由于quic版本太低,最新chrome浏览器已无法支持。

quic-go

quic-go是完全用go写的quic协议栈,开发很活跃,已在caddy中使用,mit许可,目前看是比较好的方案。它的接口和goquic接口很类似,可以参考goquic反向代理的代码,把quic部分替换为quic-go即可。最简单的实现方法,初始化一个反向代理handler直接调用h2quic.listenandservequic,主要代码如下:

import("net/http/httputil""github.com/lucas-clemente/quic-go/h2quic")proxyhandler:=httputil.newsinglehostreverseproxy("localhost:80")err=h2quic.listenandservequic(addrstr,cert,key,proxyhandler)编译部署编译

要编译这个反向代理,需要把整个chromium项目下载下来,可以按照教程操作,然后checkout这个包含代理的提交,用ninja编译,编译时只选择quic_server和quic_client即可。这个反向代理的实现,在quic_server的基础上加了一个启动选项--mode=proxy来开启反向代理模式,比如原来的服务在本机的80端口,使用原来的证书和私钥启动反向代理:

./quic_server--mode=proxy--quic_proxy_backend_url=http://localhost--certificate_file=leaf_cert.pem--key_file=leaf_cert.pkcs8

启动之后可以使用quic测试客户端连接试试看:

./quic_client--host=127.0.0.1--port=6121https://www.example.org/index.html--disable-certificate-verificationnginx配置

第一次http请求还是会从tcp端口先到达原始服务器,通过在响应中添加alt-svc头告诉客户端能够支持quic,以nginx为例,在配置文件的http块中添加:

add_headeralt-svc'quic=":443"'

这时候用chrome浏览器去访问你的网站,就可以使用quic协议了。

根据上面介绍的方法,去chrome浏览器中验证一下,如果指示器不是绿色的,可以点开看看是否(broken)了,尝试抓包查找网络原因,调整防火墙策略。

移动互联网时代,光依靠chrome浏览器可不行啊,谷歌提供了cronet,它是chromium网络协议栈的封装,可以用于android和ios平台,很方便集成到手机app中。这里可以下载编译好的cronet库。

相关文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感兴趣
推荐阅读 更多>
推荐商标

{{ v.name }}

{{ v.cls }}类

立即购买 联系客服