QUIC探索(一):初识QUIC

前言

此系列会以一系列文章来介绍Google在传输层的新开源贡献:QUIC协议 的一些内容,也是传说中未来的HTTP3。
当然,系列开篇肯定要先介绍QUIC是什么,能做什么,为什么要用QUIC这些哲学问题,所以这篇文章不会涉及一些代码层面的东西。

QUIC是什么

QUIC(全称Quick UDP Internet Connections)是谷歌公司制定的一种基于 UDP 协议的低时延互联网传输协议,它提供了多项改进,旨在加速HTTP传输并使其更加安全,目标是想最终取代TCP和TLS协议。
可以用一个公式大致概括如下:

TCP + TLS + HTTP2 = UDP + QUIC + HTTP2’s API。

【注意以上都是去别人家摘录的】

请注意,QUIC是由Google最早提出并在chromium实现,而现今交给IETF推进标准化工作。所以当前QUIC有两大分支流派,一种是基于Google的Chromium工程的QUIC实现,也叫做gQUIC;另外一种是标准化进行中的版本也叫做iQUIC。

目前两者由于协议格式、加密方式等等的不同而不能互通。当然从现时QUIC协议开源库支持度、稳定性和多平台兼容来看,比较建议采用Google主导的gQUIC,并且gQUIC在后续也会打通与iQUIC的兼容。

还有一点就是对于QUIC版本的话,在Google的源码更新进度上面看其版本迭代非常迅速,所以这里强烈不建议一味求新,除非你是大神或者想当小白鼠除外,因为每一个版本的升级导致新版本的协议格式和API变动较大而忙于处理变更。这里建议从一个稳定的版本进行入手研究,例如业界广泛支持的QUIC43/44。

QUIC的优势

低延迟连接的建立

对于传统的HTTPS来说,对于其传输层的TCP握手就需要3个RTT,如果算上加密部分的话还需要产生额外的RTT,也就是说HTTPS进行一次完全的握手至少需要4个以上的RTT。
然而对于QUIC来说,如果是客户端首次连接到服务器,由于QUIC将传输与加密结合在一起的特性所在,一般来说正常情况下初次握手只需要1个RTT就可以完成握手;但是对于触发版本协商、证书无法解密等问题当然也会导致多个RTT的产生。
而重复连接的情况下握手,如果在证书有效的情况下,客户端发送Hello包并不用等待回复就可以直接发数据加密包,也就是实现了传说中的0RTT。

改进的拥塞控制

TCP 的拥塞控制实际上包含了四个算法:慢启动,拥塞避免,快速重传,快速恢复。
QUIC协议当前默认使用TCP的拥塞控制算法,并在其基础上进行了相应的改进;当然QUIC也支持其他的拥塞控制算法。
主要的改进点有:
1、可插拔设计
2、单调递增的Packet Number
3、不允许Reneging
4、更多的Ack块
5、精确计算RTT时间

无队头阻塞的多路复用

HTTP2的最大特性就是多路复用,而HTTP2最大的问题就是队头阻塞。
首先了解下为什么会出现队头阻塞。比如HTTP2在一个TCP连接上同时发送3个Stream,其中第2个Stream丢了一个Packet,TCP为了保证数据可靠性,需要发送端重传丢失的数据包,虽然这时候第3个数据包已经到达接收端,但被阻塞了,这就是所谓的队头阻塞。
而QUIC多路复用可以避免这个问题,因为QUIC的丢包、流控都是基于Stream的,所有Stream是相互独立的,一条Stream上的丢包,不会影响其他Stream的数据传输。

前向纠错

QUIC协议的每个数据包除了本身的数据以外,会带有其他数据包的部分数据,在少量丢包的情况下,可以使用其他数据包的冗余数据完成数据组装而无需重传,从而提高数据的传输速度。具体实现类似于RAID5,将N个包的校验和(异或)建立一个单独的数据包发送,这样如果在这N个包中丢了一个包可以直接恢复出来,除此之外还可以用来校验包的正确性。

连接迁移

对于TCP协议来说,标识一个TCP连接需要4个参数,既来源IP、来源端口、目的IP和目的端口。其中的任一参数改变,TCP连接就需要重新创建。这对于传统网络来说影响不大,因为来源和目的IP相对固定。但是在无线网络中,情况就大不相同了。设备在移动过程中,可能会因为网络切换(如从WIFI网络切换到4G网络环境),导致TCP连接需要重新创建。
QUIC协议使用了UDP协议,不再需要这四元组参数。同时QUIC协议实现了自己的会话标记方式,称为连接UUID。当设备网络环境切换时,连接UUID不会发生变化,因此无需重新进行握手。

PS:基于QUIC相对于TCP的优点的网上文章已经烂大街了,其主要是出自Google的文档翻译。这里简单的进行了一些的介绍就过了,如果还想进一步了解的话建议参考其他文章或者Google发布的QUIC相关的文档,但是对于开发实战意义并非是非常重要的,只要还是源码为王,暂时觉得只是合适吹水 O(∩_∩)O

QUIC相关开源库

chromium:quic-client/server-demo模块

参考地址:https://www.chromium.org/quic
Google提供的一个QUIC的源码使用Demo,但是值得注意的其是封装了支持HTTPS的QUIC实现,如果你想在模仿TCP Socket进行QUIC传输开发的话这个方案可能不适合你。
重点敲黑板,这个Demo主要用于集成测试,其并不具备大规模的生产环境使用的性能的可能性;换句话说,它就只是一个玩具,但是这个玩具挺值得你去玩味。
PS:后续会有一篇该部分的源码简单剖析的文章。

chromium:net模块

参考地址:https://chromium.googlesource.com/chromium/src.git
如果你想在Android、iOS、Linux上面更灵活的使用QUIC的话,我觉得chromium的net模块是你的最好选择。
如果你需要封装QUIC在HTTP/HTTPS上面使用的话,可以参考上面的 quic-client/server-demo 的源码的相关使用方法,其实也就主要是研究QUIC源码库在spdy部分的内容。
如果你需要封装QUIC在更底层模仿TCP Socket操作的话,不妨看看quartc这个模块下面的API实现,具体的参考net下面的 quartc_session_test.cc 这个文件或者参考github上面的开源库posix_quic,不过后者是基于libquic的,API的调用流程并不一定适合你开发的版本,但是可以提供大方向的参考。
PS:后续的文章也大部分是基于这个模块展开。

quic-go

参考地址:https://github.com/lucas-clemente/quic-go
quic-go是使用Go语言来重写的QUIC协议实现库,从github上面看其对于iQUIC和gQUIC这两个分支流派都提供了支持,这个库当前也是比较活跃的。
从测试结果来看其稳定性和对于多端的支持相对于chromium来说仿佛就是一个小弟弟,但其也不能掩盖这个就是以前我们爸妈口中别人家的好孩子般存在。当然其性能还需要打磨,对于大规模线上应用还是需要谨慎考虑。

libquic

参考地址:https://github.com/devsisters/libquic
libquic已经有多年没有更新了,其应该是民间从chromium中提取QUIC相关源码以及其依赖项而形成一个简易的开源代码库,对于苦于需要找个梯子下载动辄数十个GB的chromium源码开发者来说,无疑是一个福音,这个库很方便我们快速尝试QUIC的开发。
其支持 ninja 和 cmake 两种编译方式,但是遗憾的是从反馈上来看这个库并不支持iOS平台的编译。
基于这个平台的 HTTP 封装实现有 goquic 和 TCP Socket 封装实现有 posix_quic

proto-quic

参考地址:https://github.com/google/proto-quic
这个库是Google在chromium上面抽取出来发布于github的一个快速验证QUIC的开源库,同libquic一样并不需要下载太多的源码,但是其仅仅保证在Ubuntu上是可用的,现在Google已经转向了quiche这个开源分支上面进行独立QUIC库的开发。
在笔者写这篇文章的时候,其github上面的代码已经被清空;不难预期这个源码被整个删库跑路的日子也不会太远了。

quiche

参考地址:https://quiche.googlesource.com/quiche
更新速度极快的谷歌QUIC开源代码库,其主要目的是希望将QUIC从chromium这个庞大的库独立出来作为其上游的实现方案来提供QUIC协议的支持,但是由于其也只是刚刚开始从 https://cs.chromium.org/chromium/src/net/third_party 中迁移过来,目前相关文档比较缺乏而且源码结构变动过大;暂时并不建议入手研究,但是强烈建议重点关注。

chromium:Cronet模块

参考地址:https://developer.android.com/guide/topics/connectivity/cronet
Cronet主要为chromium的net模块进行了Android/iOS端的封装,并提供了相应的Java和OC接口,所以我们在移动端也是可以通过Cronet使用net模块里面QUIC协议。如果在客户端APP想要快速验证使用基于QUIC的HTTP请求的话,Cronet是一个非常合适的方案,但是在简单使用的前提下其灵活性也相对较差。

Stellite

参考地址:https://github.com/line/stellite
这个是利用了Cronet,用C++封装了一层API而得到的这个Stellite开源库,解决了我们希望能在C/C++层面进行简单快速使用QUIC相关协议的需求。当然,对于灵活性和效率肯定没有比不上chromium的原生逻辑实现。

Caddy

参考地址:https://github.com/mholt/caddy
Caddy是当前支持QUIC的一个比较健壮的Web服务器,其底层是基于quic-go的实现。相对于nginx等框架还未提供对quic的支持,实验性支持quic的caddy也是当前web服务器支持QUIC协议的唯一理想选择。

结语

好了,这篇文章主要目的就是简单介绍一下QUIC这个协议,以及可用于研究QUIC的一些开源库,接下来主要会围绕chromium库来介绍一下基于QUIC的相关开发工作。

本文发布于 简书

End!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • 本文来自于腾讯 Bugly 公众号(weixinBugly), 作者:emilymmwang,未经作者同意,请勿转...
    Erbash阅读 6,555评论 2 10
  • 科普:QUIC 协议原理分析 作者介绍:lancelot,腾讯资深研发工程师。目前主要负责腾讯 stgw(腾讯安全...
    吸霾少年阅读 9,671评论 0 19
  • 今天是幼儿园家长绘本分享日 起床:五点半 就寝:应该就是晚上九点半,每天都是这个点 天气:天气预报报的多云 心情:...
    木星上阅读 106评论 0 0
  • 今天要拆的书是《史上最简单的问题解决手册》的片段。 I:片段中讲了送礼的两个思考的角度,一个是认识时间的长短,一个...
    Mr绍君阅读 263评论 0 0
  • 近日一篇公号文章《一个出身寒门的状元之死》,成为10万+阅读的爆款文章,刷屏朋友圈。 文章描述的是一个...
    深圳的高中生阅读 648评论 1 6