0x01 Quic

QUIC协议于2012年实现,2015年提交RFC草案,它是Goolge为了解决当今WEB应用常见的传输层和应用层问题而提出的,从分层结构上可以看做是TCP+TLS+HTTP2的集合,不过是在UDP的基础上实现的

主要解决了下面的几个问题

  1. Connection establishment latency(连接时延)
  2. Flexible congestion control (拥塞控制)
  3. Multiplexing without head-of-line blocking (HOLB问题)
  4. Authenticated and Encrypted Header and Payload (头部加密)
  5. Forward error correction (前向纠错)
  6. Connection migration(连接迁移)

0x02 HOLB问题

HOLB(Head of Line Blocking),当所有请求必须按序执行时,会造成后续请求即使已经达到处理的条件也会由于前面的请求阻塞而阻塞的现象。网络中大量存在着按序的原则,例如路由器转发队列需要按序转发、TCP报文需要按序到达等,HTTP请求在多个层次上也都存在该问题,

HTTP事务级别的 HOLB

在HTTP1.0时代,HTTP请求只能遵循请求-应答、请求-应答的模式,效率极低,一般浏览器都开启多条流来并行多个请求(Chrome 6条)。HTTP1.1引入了Pipelining机制,实现流水线请求,客户端可以一次性向服务端发送多个请求,但HTTP 1.X要求多个HTTP响应必须按序到达,例如请求r1和r2的响应各有几个报文,[r1p1, r1p2]和[r2p1, r2p2],HTTP1.X要求报文按序到达,后面的请求被前面的请求阻塞在服务器,造成了HTTP层面的HOLB问题,大多数浏览器因此并没有采用Pipelining而是沿用之前的多流机制。SPDY打破了HTTP1.X的交付顺序,允许响应报文乱序到达,例如按照[r2p1, r1p1, r1p2, r2p2]的顺序到达,从而解决了HTTP事务层面的HOLB问题。

TCP级别的 HOLB

SPDY解决了HTTP事务层的HOL问题,但无法解决TCP层的HOL问题。TCP的可靠性要求所有数据按序交付应用层,发生丢包时接收端会收到大量乱序(Out of Order)的报文,这些报文只能暂时缓存在TCP接收缓冲区中,并不能交付应用层,造成后面请求响应报文由于前面请求响应报文的丢包而不能被应用层读取。UDP就不存在这个问题,应用层可以提前读取乱序但有价值的数据,在采取多路复用时,不会因为某个响应丢包而造成所有响应都被阻塞在内核缓冲区中,因此Quic采用UDP作为传输层协议。

0x03 连接建立时间

基于传统TCP的WEB应用每次请求至少经过1-3个RTT才能建立连接,包括TCP三次握手和TLS交换秘钥的时间,在长连接中,这点时间不算什么,但在短流时,连接建立时间可能在响应时间内占有相当大的比重,Google也做了相当多的工作来优化连接建立时间。

早些年,Google还搞过TFO(TCP Fast Open )用来加速连接的建立,传统TCP其实可以在SYN报文内携带数据的,只不过应用层无法在三次握手前读取[rfc793],主要在可靠性与安全方面的考虑,在三次握手前就交付数据可能会带来几个问题,一个就是SYN-Flood攻击可以直接向服务器传输数据。TFO通过Cookie的方式防御这种攻击,服务器在初始连接中向客户端发送一个Cookie,之后客户端通过该Cookie向服务器证明自己,服务端在SYN-ACK报文内就可以发送数据了,减少了整整一个RTT的时间。

QUIC同样采用了Cookie的机制来验证客户端的合法性,从而将整个连接建立过程减少到至多1个RTT,除了在初始连接中服务器需要发送证书和Cookie之外,客户端都可以直接用Cookie在建立连接的同时发送数据。

0x04 其它特性

拥塞控制算法

TCP的拥塞控制算法一直被诟病,以至于UDT、KCP等都是基于UDP实现自己的可靠性与拥塞控制。Quic目前拥塞控制算法目前采用Cubic。Quic的ACK报文中携带这接收端在接收报文与发送ACK报文之间的时间间隔,发送端根据该间隔可以更精确地测量链路时延,TCP-Vegas等基于时延的拥塞控制算法在将来都有在其基础上实现的可能。

前向纠错(Forward Error Correction)

FEC机制下每隔几个报文就发送一个FEC报文,FEC报文为一组报文的异或,在发生丢包时,可以通过未丢失的报文和FEC报文将丢包恢复出来,减少了不必要的重传。QUIC若干个报文组成一个FEC组,这样增加了每个报文的负载,但减少了重传,是一种空间换时间的做法,报文冗余度是一个可控的参数,冗余度越大消耗的带宽越大,同时减少了重传数。QUIC类似于RAID4

连接迁移(Connection Migration)

一条TCP流由原宿IP、原宿端口和协议来标识,而一条Quic流由一个变长ID(0,8,32,64位)唯一标识,这样Quic流并不依赖于IP地址。一方面,当某个网卡崩溃后,QUIC并不需要重新建立连接,只需要切换到另外一个网卡,提高了可靠性;另一方面,QUIC天然具备了Multipath的特质,让多个网卡同时工作,通过添加调度器和多流拥塞控制算法,QUIC可以实现MPTCP的功能,而且是在一个更高的层次上。

0x05 搭建Quic服务器

google自己的chromium项目里已经支持了QUIC,不过不够方便,go语言编写的WEB服务器Caddy已经能够较好地支持Quic与HTTP2.0了,已经在个人服务器上搭建了Caddy-Server,地址为 https://m.codingmozart.com/ ,当然在Google的各大网站不断F5也是可以看到QUIC的。

Chrome浏览器已经支持QUIC,通过chrome://flags/#enable-quic开启QUIC功能,并在chrome://net-internals/#quic里可以看到所有活跃的QUIC流。

Wireshark可以抓到QUIC的包,在报头部分可以看到连接号CID(Connection ID)和报文号Sequence类似于TCP的Seq,报文的主要内容被编码在了负载部分

QUIC有三种类型的报文

Frame Packet:携带一个个数据帧,数据帧类型包括ACK,STREAM,WINDOW_UPDATE等等,其中STRAM类型的Frame就是用来实现Multiplexing的,一个帧可以携带多条流的分片。

 +--------+---...---+--------+---...---+
| Type | Payload | Type | Payload |
+--------+---...---+--------+---...---+

FEC Packet:携带一组报文的异或,用来前向纠错

 +-----...----+
| Redundancy |
+-----...----+

Public Reset Packet

      0        1        2        3        4         8
+--------+--------+--------+--------+--------+-- --+
| Public | Connection ID (64) ... | ->
|Flags(8)| |
+--------+--------+--------+--------+--------+-- --+ 9 10 11 12 13 14
+--------+--------+--------+--------+--------+--------+---
| Quic Tag (32) | Tag value map ... ->
| (PRST) | (variable length)
+--------+--------+--------+--------+--------+--------+---

0x06 参考文献

[1] https://tools.ietf.org/html/draft-tsvwg-quic-protocol-00#ref-QUIC-CRYPTO

Google Quic协议的更多相关文章

  1. Google将向IETF标准提交QUIC协议提案

    Google近期宣布,他们将向IETF提交实验性传输层网络协议QUIC的提案.此外,Google已经给出了QUIC协议优化页面加载时间的第一手数据. 自从2013年引入QUIC以来,Google一直在 ...

  2. Google 打算用 QUIC 协议替代 TCP/UDP

    有句话叫做一流企业定标准.二流企业做品牌.三流企业卖技术.四流企业做产品.Google 似乎在冲着一流企业的目标迈进.去年,Google 已经从以 SPDY 为基础的 HTTP 协议 16年 来的首个 ...

  3. 让互联网更快:新一代QUIC协议在腾讯的技术实践分享

    本文来自腾讯资深研发工程师罗成在InfoQ的技术分享. 1.前言 如果:你的 App,在不需要任何修改的情况下就能提升 15% 以上的访问速度,特别是弱网络的时候能够提升 20% 以上的访问速度. 如 ...

  4. QUIC协议的分析,性能测试以及在QQ会员实践

    WeTest 导读 你听过HTTPS.HTTP2.0.SPDY,但是这些应用层协议都是基于可靠的传输层协议TCP来实现的.那么,基于高效的UDP协议有没有一种相对可靠的应用层协议呢? Why QUIC ...

  5. QUIC协议原理分析(转)

    之前深入了解了一下HTTP1.1.2.0.SPDY等协议,发现HTTP层怎么优化,始终要面对TCP本身的问题.于是了解到了QUIC,这里分享一篇之前找到的有意义的文章. 原创地址:https://mp ...

  6. QUIC协议

    QUIC协议 QUIC协议参考网址 https://www.chromium.org/quic 既生瑜,何生亮? QUIC的特性 提供可靠传输 减少连接建立的时间 改善拥塞控制 多路复用 转发错误连接 ...

  7. 一泡尿的时间,快速读懂QUIC协议

    1.TCP协议到底怎么了? 现时的互联网应用中,Web平台(准确地说是基于HTTP及其延伸协议的客户端/服务器应用)的数据传输都基于 TCP 协议. 但TCP 协议在创建连接之前需要进行三次握手(如下 ...

  8. 网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议

    1.TCP协议到底怎么了? 现时的互联网应用中,Web平台(准确地说是基于HTTP及其延伸协议的客户端/服务器应用)的数据传输都基于 TCP 协议. 但TCP 协议在创建连接之前需要进行三次握手(如下 ...

  9. [译] QUIC Wire Layout Specification - Frame Types and Formats | QUIC协议标准中文翻译(4) 帧类型和格式

    欢迎访问我的个人网站获取更好的阅读排版体验: [译] QUIC Wire Layout Specification - Frame Types and Formats | QUIC协议标准中文翻译(4 ...

随机推荐

  1. 7.20 Codeforces Beta Round #8

    链接:codeforces.com/contest/8 A 原因:RE,fantasy 的字符串的长度可能大于原字符串. B 题意:上下左右走,可能要避让障碍,问是否存在一个地图使得给定的路径为当前最 ...

  2. Java 问题定位工具 ——jstack

    简介 jstack 主要用于生成虚拟机当前时刻的「线程快照」.线程快照是当前 Java 虚拟机每一条线程正在执行的方法堆栈的集合. 生成线程快照的主要目的是用于定位线程出现长时间停顿的原因,如线程间死 ...

  3. shell编程(六)之数组

    数组: 存储多个元素的连续的内存空间 索引: 编号从0开始,属于数值索引 注意:索引也可支持使用自定义的格式,而不仅仅是数值格式 声明数组: declare -a ARRAY_NAME declare ...

  4. git Remote: HTTP Basic: Access denied Git failed with a fatal error.

    解决方案: git clone 项目失败,报下面的错误信息: $ git clone http://192.168.0.141/xxxx.git Cloning into 'appEnterprise ...

  5. Linux操作系统的VI命令

    Linux操作系统的VI命令 VI是Linux系统的一个文本编辑器,该编辑器可以通过使用VI命令来操作,从而完成对文本的编辑.熟练掌握一些常用的VI命令,可以大大简化编辑操作并提高操作Linux文本的 ...

  6. linux中centros6.7安装php5.6,httpd-2.2.19(web产品化)遇到的问题总结

    前段时间在公司实习,web系统产品化的过程踩了很多坑,在这边总结一下,由于对linux不是很懂,全是自己一步步一个一个问题解决的 1,查看系统中是否安装apache,php,mysql环境 Apach ...

  7. Pandas 基础(16) - Holidays

    这节依然是关于时间方面的知识.上一节学习了如何获取日期序列的函数, 以及通过一些基本的参数设置可以使时间序列跳过休息日等.这一节, 将要深入学习这个点, 做更自定义的设计. 通过上一节的学习, 我们知 ...

  8. 关于Ocelot和Consul 实现GateWay(网关) 服务注册 负载均衡等方面

    Ocelot   路由  请求聚合  服务发现 认证  鉴权 限流熔断 内置负载均衡器 Consul   自动服务发现    健康检查 通过Ocelot搭建API网关   服务注册   负载均衡 1. ...

  9. Android人脸识别Demo竖屏YUV方向调整和图片保存

    本博客包含三个常用方法,用于盛开Android版人脸识别Demo中竖屏使用时送入yuv数据,但一直无法识别的情况. 1.首先可以尝试顺时针旋转90°或270°,然后送入识别SDK. 2.旋转方向后依然 ...

  10. Java分布式锁看这篇就够了

    ### 什么是锁? 在单进程的系统中,当存在多个线程可以同时改变某个变量(可变共享变量)时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量. 而同步的本质是通过锁来实现的 ...