编程技术文章分享与教程

网站首页 > 技术文章 正文

QUIC的前世今生 谁的前世今生

hmc789 2024-11-13 11:32:31 技术文章 2 ℃

1、 QUIC出现背景

1.1. 基于HTTP的应用需求不断变化

基于TCP协议 的 HTTP 协议是互联网上应用最为广泛的一种网络协议,起初HTTP协议主要是用来将超文本标记语言 (HTML) 文档从 Web 服务器传送到客户端的浏览器。到了 Web 2.0 时代,HTML 页面变得越来越复杂,不仅仅单纯的是一些简单的文字和图片,同时有了层叠样式表 (Cascading Style Sheets,CSS),JavaScript (一种直译式脚本语言) 来丰富页面展示,随着 ajax (一种创建交互式网页应用的网页开发技术,英文全称: Asynchronous JavaScript And XML) 的出现,客户端又多了一种向服务器端获取数据的方法,这些其实都是基于 HTTP 协议的。特别是移动互联网时代,页面可以在手机端浏览器里显示,和电脑端相比,手机端的网络情况更加复杂,经常涉及到蜂窝网络与无线局域网之间的切换,因此需要对 HTTP协议 进行深入理解并不断优化 。

1.2. HTTP各版本回顾

HTTP/0.9 是一个过时的协议,它只接受 GET 一种请求方法,没有在网络传输中指定版本号,且不支持请求头。由于该版本不支持 POST 方法,因此客户端无法向服务器传递太多信息。

随后提出的 HTTP/1.0 是第一个指定版本号的 HTTP 协议版本,早期只是使用在一些较为简单的网页和网络请求上,现在主要是在代理服务器中使用。

HTTP/1.1 在 1999 年开始广泛应用于现在的各大浏览器网络请求中,同时也是当前使用最为广泛的 HTTP 协议。HTTP/1.1 与 HTTP/1.0 的主要区别如下 :

(1) 缓存处理。在 HTTP/1.0 中主要使用 header 里的 If-Modified-Since, Expires作为缓存判断的标准,HTTP/1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

(2) 带宽优化及网络连接的使用。HTTP/1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象传过来了,并且不支持断点续传功能,HTTP/1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。

(3) 错误通知的管理。在 HTTP/1.1 中新增了 24 个错误状态响应码,如 409 (Conflict) 表示请求的资源与资源的当前状态发生冲突 ; 410 (Gone) 表示服务器上的某个资源被永久性的删除。

(4) Host 头处理。在 HTTP/1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此请求消息中的 URL 并没有传递主机名 (hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个 IP 地址。HTTP/1.1 的请求消息和响应消息都应支持 Host 头域,且请求消息中如果没有 Host 头域会报告一个错误(400 Bad Request)。

(5) 长连接。HTTP/1.1 支持长连接 (Persistent Connection) 和请求的流水线 (Pipelining) 处理,在一个 TCP 连接上可以传送多个 HTTP 请求和响应,减少了建立和关闭连接的消耗和延迟,在 HTTP/1.1 中默认开启 Connection: keep-alive,一定程度上弥补了 HTTP/1.0 每次请求都要创建连接的缺点。

尽管 HTTP/1.1 相比于 HTTP/1.0 有了很大的优化,但仍存在不少问题。

(1) 需要很多 TCP 连接来实现并发请求与响应,且在传输数据时每次都需要重新建立连接,这增加了大量的延迟时间并可能引起网络拥塞和高数据包丢失,导致更差的网络性能。

(2) 在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,这在一定程度上无法保证数据的安全性。

(3) 头部信息 (header) 里携带的内容过大,在一定程度上增加了传输的成本,并且每次请求 header 基本不怎么变化,尤其在移动端环境下容易增加用户流量。

(4) 虽然 HTTP/1.1 支持了 keep-alive,来弥补多次创建连接产生的延迟,但是 keep-alive 使用多了同样会给服务端带来大量的性能压力。

(5) HTTP 请求严格由客户端发起,在网页加载很多嵌入对象时会严重影响性能,因为服务器只能在客户端发出请求后才能传输数据。

SPDY 是一种基于 TCP 的开放网络传输应用层协议,由 Google 开发,用来发送网页内容。设计 SPDY 的目的在于降低网页的加载时间,与 HTTP/1.1 相比,它在以下几方面作了改进。

(1) 降低延迟。针对 HTTP 高延迟的问题,SPDY 采取了多路复用 (multiplexing)。多路复用通过多个请求流共享一个 TCP 连接的方式,同时服务端也可通过一个连接发出多个应答流,提高了服务端性能。多路复用技术可以减少网络拥塞、降低延迟,同时提高了带宽的利用率。

(2) 请求优先级。多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY 允许给每个请求设置优先级,这样重要的请求就会优先得到响应。比如浏览器加载首页,首页的 html 内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容。

(3) header 压缩。HTTP 1.x 的 header 很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量,降低延迟。

(4) 基于 HTTPS 的加密协议传输,大大提高了传输数据的可靠性。SPDY中广泛应用了安全传输层协议 (Transport Layer Security,TLS) 加密,传输内容也均以 gzip 或 DEFLATE 格式压缩。

(5) 服务端推送。采用了 SPDY 的网页,在客户端发出一个资源请求时,服务端会把相关的资源主动推送到客户端而避免等待客户端再发出请求后响应。这可以减少页面加载时间。需要说明的是,SPDY 并不用于替换 HTTP,它只是修改了 HTTP 的请求与应答在网络上传输的方式; 这意味着只需增加一个 SPDY 传输层,现有的所有服务端应用均不用做任何修改。当使 用SPDY 的方式传输时,HTTP请求会被处理、标记简化和压缩。比如,每一个 SPDY 端点会持续跟踪每一个在之前的请求中已经发送的 HTTP 报文头部,从而避免重复发送还未改变的头部。而还未发送的报文的数据部分将在被压缩后被发送。SPDY 的构成如图 1 所示。

2015 年推出的 HTTP/2 大部分基于 SPDY 实现,主要区别为 :

(1) HTTP/2 支持明文 HTTP 传输,而 SPDY 强制使用 HTTPS。

(2) HTTP/2 消息头 (header) 的压缩算法采用 HPACK,而非SPDY 采用的 DEFLATE。由于 HTTP/2 推出时间不长,相较于 HTTP/1.1 应用范围还不广,但是未来肯定会逐渐取代 HTTP/1.1。

1.3. HTTP/2 的局限性

前面几种协议都是基于 TCP。TCP 因其面向连接、可靠传输等特点而被广泛采用,但在如今带宽越来越大的网络环境下,TCP 的局限性也制约了 HTTP/2 的性能,主要表现为以下两点。

(1) 数据传输前 TCP 先要进行"三次握手",建立连接后才开始传输应用数据,这无疑增加了网络延时; 在采用 TLS 协议时需要交换密钥,这又增加了一次往返时延 (Round-Trip Time,RTT)。

(2) HOL (Head-of-line) blocking,前序包阻塞。TCP 保证有序传输,所以当一个数据包丢失时,其他所有的包都要等它重传整理后才会交给应用层,对于多路复用共享一个 TCP 连接的 SPDY 和 HTTP/2 来说,这无疑影响更大。

2、 QUIC协议概述

QUIC(Quick UDP Internet Connections)协议是一种全新的基于UDP的web开发协议。可以用一个公式大致概括:

TCP + TLS + HTTP2 = UDP + QUIC + HTTP2's API

从公式可看出:QUIC协议虽然是基于UDP,但它不但具有TCP的可靠性、拥塞控制、流量控制等,且在TCP协议的基础上做了一些改进,比如避免了队首阻塞;另外,QUIC协议具有TLS的安全传输特性,实现了TLS的保密功能,同时又使用更少的RTT建立安全的会话。可见QUIC可以很好的解决前述基于TCP的HTTP协议所面临的困难。

3、 QUIC协议原理

3.1. 低建立连接延迟 (Connection Establishment Latency)

建立一个TCP连接需要进行三次握手,这意味着每次连接都会产生额外的RTT,从而给每个连接增加了显著的延迟(如图2所示)。

另外,如果还需要TLS协商来创建一个安全的、加密的https连接,那么就需要更多的RTT,无疑会产生更大的延迟(如图2所示)。

QUIC协议第一次Client和Server建立连接还是会走正常的TLS握手流程,但过了一会儿或者一段时间后,Client又想和Server通信,此时Client已经有了刚刚和Server协商出来的密钥(可能是存在内存也可能swap到硬盘)。Client就会利用刚刚的密钥K1来和Server加密首次数据,在第二个RTT期间,Server会和Client协商出新的密钥K2,作为接下来的通信密钥。如果一对使用QUIC进行加密通信的双方此前从来没有通信过,0 RTT是不可能的。

3.2. 改进的拥塞控制 (Improved Congestion Control) QUIC协议当前默认使用TCP协议的Cubic拥塞控制算法。并在TCP拥塞算法基础上做了些改进:

(1) 可插拔

· 应用程序层面就能实现不同的拥塞控制算法,不需要操作系统或内核支持。

· 单个应用程序的不同连接也能支持配置不同的拥塞控制。

· 不需要停机和升级就能实现拥塞控制的变更。

(2) 单调递增的Packet Number

TCP重传的包的sequence number和原始的包的Sequence Number是保持不变的,也正是由于这个特性,引入了Tcp重传的歧义问题。

超时事件RTO发生后,客户端发起重传,然后接收到了Ack数据。由于Sequence Number一样,这个Ack 到底是原始请求的响应还是重传请求的响应呢?这就间接导致了RTT计算的歧义。

Quic使用Packet Number代替了TCP的sequence number,并且每个Packet Number都严格递增,也就是说就算Packet N丢失了,重传的Packet N的Packet Number 已经不是N,而是一个比N大的值,这就解决了RTT计算的歧义问题。

(3) 更多的ACK块

QUIC ACK帧支持256个ACK块,相比TCP的SACK在TCP选项中实现,有长度限制,最多只支持3个ACK块

(4) 精确计算RTT时间

QUIC ACK包同时携带了从收到包到回复ACK的延时,这样结合递增的包序号,能够精确的计算RTT。

TCP的RTT计算:

Quic的RTT计算:

3.3. 无队头阻塞的多路复用 (Multiplexing without head-of-line blocking)

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

3.4. 保证包的顺序

假设Packet N丢失了,发起重传,重传的Packet Number是N+2,但是它的Stream的Offset依然是x,这样就算Packet N + 2是后到的,依然可以将Stream x和 Stream x+y 按照顺序组织起来。

3.5. 前向纠错 (Forward Error Correction)

QUIC使用了FEC(前向纠错码)来恢复数据,FEC采用简单异或的方式,每发送一组数据,包括若干个数据包后,并对这些数据包依次做异或运算,最后的结果作为一个FEC包再发送出去。接收方收到一组数据后,根据数据包和FEC包即可以进行校验和纠错。比如:10个包,编码后会增加2个包,接收端丢失第2和第3个包,仅靠剩下的10个包就可以解出丢失的包,不必重新发送,但这样也是有代价的,每个UDP数据包会包含比实际需要更多的有效载荷,增加了冗余和CPU编解码的消耗。

3.6. 连接迁移 (Connection Migration)

TCP的连接是基于4元组的,而QUIC使用64为的Connection ID进行唯一识别客户端和服务器的逻辑连接,这就意味着如果一个客户端改变IP地址或端口号,TCP连接不再有效,而QUIC层的逻辑连接维持不变,仍然采用老的Connection ID。

4、 QUIC应用场景

4.1. 长距离传输

4.2. 手机网络

4.3. 请求的页面资源数较多,并发的连接数多

4.4. 要求加密传输

4.5. 弱网环境的时候能够提升 20% 以上的访问速度。

4.6. 频繁切换网络的情况下,不会断线,不需要重连,用户无任何感知。

5、 参考资料

1. [1] Megyesi P, Kr?mer Z, Molnár S. How quick is QUIC[C] Communications (ICC), 2016 IEEE International Conference on. IEEE, 2016: 1-6.

2. [2] Biswal P, Gnawali O. Does QUIC make the Web faster[C] Global Communications Conference (GLOBECOM), 2016 IEEE. IEEE, 2016: 1-6.

3. [3] Gratzer F. QUIC-Quick UDP Internet Connections[J]. Future Internet (FI) and Innovative Internet Technologies and Mobile Communications (IITM), 2016, 39.

4. [4] Carlucci G, De Cicco L, Mascolo S. HTTP over UDP: an Experimental Investigation of QUIC[C] Proceedings of the 30th Annual ACM Symposium on Applied Computing. ACM, 2015: 609-614.

5. 下一代通信协议:Quic

https://knownsec-fed.com/2018-01-19-xia-yi-dai-tong-xin-xie-yi-quic/

6. QUIC协议是如何做到0RTT加密传输的

https://blog.csdn.net/dog250/article/details/80935534

7. Web服务器快速启用QUIC协议

https://my.oschina.net/u/347901/blog/1647385

8. QUIC协议原理分析

https://zhuanlan.zhihu.com/p/32553477

9. QUIC在腾讯的实践及性能优化

https://zhuanlan.zhihu.com/p/32560981

10. 七牛云 QUIC 推流方案如何实现直播 0 卡顿

https://zhuanlan.zhihu.com/p/33698793

11. 当我们在讨论http队头阻塞时,我们在讨论什么?

https://liudanking.com/arch/what-is-head-of-line-blocking-http2-quic/

12. QUIC官方文档

https://www.chromium.org/quic

13. QUIC协议规范https://www.wolfcstech.com/2017/01/13/QUIC%E5%8D%8F%E8%AE%AE%E8%A7%84%E8%8C%83/

标签列表
最新留言