昨天在参加阿里 D2 的时候听腾讯的黄佳琳老师分享 QQ空间HTTP2加速实践 时她提到在今 QQ 空间 2017年开始使用 QUIC 协议。看到 QUIC 时就想腾讯这么冒进了敢用它!!!至于为什么会这么想,请继续。
QUIC
QUIC 是谷歌在 2013 年实现,2014 推出的一种实验性的传输层网络传输协议。 QUIC 全称是 Quick UDP Internet Connections 就是快速 UDP 网络连接。一个它以UDP为基础,实验性传输层协议。
TCP 和 UDP
web 平台的数据传输都基于 TCP 协议。TCP协议在创建连接之前需要进行三次握手,如果需要提高数据交互的安全性,既增加传输层安全协议(TLS),还会增加更多的握手次数。
正因为TCP协议连接建立的成本相对较高,可以通过TCP快速打开(TCP Fast Open)来减少建立连接时的握手次数。但是该技术目前应用较少。
UDP协议是无连接协议。客户端发出UDP数据包后,只能“假设”这个数据包已经被服务端接收。这样的好处是在网络传输层无需对数据包进行确认,但存在的问题就是为了确保数据传输的可靠性,应用层协议需要自己完成包传输情况的确认。
来源维基百科 : 对于 Google 来说优化 TCP 协议是一个长期目标,QUIC 旨在创建几乎等同于 TCP 的独立连接,但有着低延迟,并对类似 SPDY 的多路复用流协议有更好的支持。 如果 QUIC 协议的特性被证明是有效的,这些特性以后可能会被迁移入后续版本的 TCP 和 TLS 协议(它们都有很长的开发周期)。
TCP 协议的实现是高度管制的。TCP 协议栈通常由操作系统实现,如 Linux、Windows 内核或者其他移动设备操作系统。修改 TCP 协议是一项浩大的工程,因为每种设备、系统的实现都需要更新。
UDP 协议在操作系统层面实现相对简单,基于 UDP 协议实现新的协议以验证 Google 对于 TCP 协议改进的理论,不需要操作系统内核层面的更改,验证成本相对较低。
可以说 QUIC 是夹在 HTTP2 和 UDP 的中间部分就像汉堡。

QUIC 特点
QUIC 协议的主要目的,是为了整合 TCP 协议的可靠性和 UDP 协议的速度和效率。
避免队头阻塞
HTTP 1.1 协议的并发请求并非是直接解决了 HOC 的问题,而是尽可能减少 HOC 造成的影响。
SPDY 它采用了多路复用(Multiplexing) 技术也是解决不了这个问题。TCP 协议如果发生了丢包或者错包,数据就会被重传,后面的包就得停下来等这个包重新传输,也就是发生了队头阻塞,TCP 协议的设计者们又发明了滑动窗口,滑动窗口的概念大幅度提高了 TCP 传输数据时抗干扰的能力,一般丢失一两个 ACK 根本没关系。但如果是发送的包丢失,或者出错,窗口就无法向前滑动,出现了队头阻塞的现象。
队头阻塞不仅仅在 HTTP 层存在,在 TCP 层也存在,这也正是 QUIC 协议要解决的问题。QUIC 协议也采用了多路复用思想。
QUIC协议直接通过底层使用 UDP 协议天然的避免了 SPDY 和 HTTP/2 协议由于 TCP 协议在处理包时是有严格顺序而遇到前序包阻塞的问题。由于UDP协议没有严格的顺序,当一个数据包遇到问题需要重传时,只会影响该数据包对应的资源,其他独立的资源不会受到影响。
重传与恢复
丢包恢复一共有两种方法:前向纠错(FEC)和重传。前向纠错可以减少重传,但需要在保重添加冗余信息,用 XOR 实现。如果前向纠错不能回复包,才启用重传,重传的不是旧包,而是重新构造的包。
前向纠错(FEC):FEC 采用简单异或的方式(也就是相同数字异或成 0,不同数字异或成 1)。每次发送一组数据,包括若干个数据包后,并对这些数据包依次作异或运算,最后的结果作为一个 FEC 包再发送出去。接收方收到一组数据后,根据数据包和 FEC 包即可以进行校验和纠错。
对于某些重要的数据包,如初始密钥协商时的数据包,在建立连接时非常重要,如果这类包丢失会阻塞整体数据流。QUIC 对于这一类数据包在确认发生丢失前就会尝试重传,通常是等待较短的时间(如20ms)没收到确认后就马上再次发送。这样在网络中会有若干个相同的包同时传输,只要有一个能成功抵达就完成了连接,这样降低了丢包率。接收方对于关键数据包的多次发送和普通数据包的超时重传,都采用相同的重复包处理机制
QUIC在拥塞避免算法的基础上还加入了心跳包,用于减少丢包率
减少数据包
QUIC协议在创建连接握手时,只需要1到2个数据包对比传统TCP+TLS协议的传输方式,在创建连接时的4个数据包。
TCP 快速打开 0 个 RTT
核心思想:将当前会话的上下文缓存在客户端。如果以后需要恢复对话,只需要将缓存发给服务器校验,而不必花费一个 RTT 去等待。
QUIC 握手的过程是需要一次数据交互,0-RTT 时延即可完成握手过程中的密钥协商,比 TLS 相比效率提高了5倍,且具有更高的安全性。 QUIC 在握手过程中使用 Diffie-Hellman 算法协商初始密钥,初始密钥依赖于服务器存储的一组配置参数,该参数会周期性的更新。初始密钥协商成功后,服务器会提供一个临时随机数,双方根据这个数再生成会话密钥。安全性
QUIC 协议内置了 TLS 栈,实现了自己的传输加密层,QUIC 对每个散装的 UDP 包都进行了加密和认证的保护,并且避免使用前向依赖的处理方法(,这样每个 UDP 包可以独立地根据 IV 进行加密或认证处理。 QUIC 采用了两级密钥机制:初始密钥和会话密钥。初次连接时不加密,并协商初始密钥。初始密钥协商完毕后会马上再协商会话密钥,这样可以保证密钥的前向安全性,之后可以在通信的过程中就实现对密钥的更新。接收方意识到有新的密钥要更新时,会尝试用新旧两种密钥对数据进行解密,直到成功才会正式更新密钥,否则会一直保留旧密钥有效。
使用
启用
Chrome 浏览器(版本50.0或更高)中打开地址:
chrome://flags/在Experimental QUIC protocol 项目勾选 Enabled;然后重启。
查看站点是否通过 QUIC 通信
使用Chrome 选项卡
chrome://net-internals/#quic
Chrome 插件
插件
HTTP/2 and SPDY indicatorHTTP/2显示蓝色标志,HTTP/2 + QUIC 显示绿色,可以看到 QQ 空间没用 HTTP/2 + QUIC。
总结
- QUIC 目前处于实验阶段国内”不存在”的协议
- QUIC 是基于 UDP 的同为传输层
- UDP 通信,所以服务器上的防火墙要打开。网站或项目的服务器需要有传入 443/UDP 的策略,对于客户端来说,允许 443/UDP 接入互联网
- 想想就目前国内宽带运营商的各种 UDP 限制 。。
PS: 今天重新看了下黄佳琳老师分享并没有说支持 QUIC 只是说了 2017 在实验 。。