从http到QUIC

零、为何要分享这个主题?

  • chorme浏览器已经支持quic协议(虽然为了安全默认关闭,仍是草案中),但quic有望大大下降首次首屏的加载时间,解决困扰咱们好久首次渲染的性能问题。
  • http3草案: quicwg.org/base-drafts…

1、http的发展史

首先先来回顾下http的发展历程,了解下http是如何来的。html

  • http是在1965年,由Ted Nelson提出的,并在Xanadu项目中实现超文本系统的原型
  • 在1989年,Tim Berners-lee提出了'超文本'(以一种无约束的方式联系起来的人类可读信息)和‘超媒体’(不限于文本),搭建“"通用系统"。
  • 在1991年,就提出http/0.9,可是比较简单,并且只有get方法,没有首部,只能获取html,没有图片和文本
  • 在1996年,提出了http/1.0,这时候就包括首部、响应码、重定向、错误、条件请求、内容编码(压缩)等等。可是不包括共用请求,强制的host首部,缓存的选择
  • 在1999年,提出的http/1.1,这时候就强制host首部,有虚拟主机托管,不用每一个请求发起tcp链接。同时也扩展了缓存相关首部、options方法、upgrate首部、Range请求、压缩和传输编码、管道化
  • 在2009年,Google工程师Mike Belshe和Roberto Peon提出了SPDY,在http以前作了一层会话。
  • 在2015年,提出了http/2.0,融合SPDY的优点,使用了二进制分帧层,多路复用,头部压缩,服务器推送等等。。。
  • 如下就是我整理的http发展的时间线

2、http2的特性和详解

  • 一、名词认识:
    • SPDY(读做“SPeeDY”)是Google开发的基于TCP的会话层协议,用以最小化网络延迟,提高网络速度,优化用户的网络使用体验。就是在应用层中增长1个SPDY协议,以下图所示,在本来的应用层中,增长了SPDY层。
    • 数据帧:http/2大体分为分帧层和数据层。数据帧第一个是length,以后是帧的类型,flags就带有帧的标识。
    • 流:
  • 二、特性:
    • (1)、二进制传输,原来HTTP/1.x 是以纯文本形式的报文,到了HTTP/2就 采用二进制格式传输数据。以下看两种的区别。
      • 纯文本解析:以纯文本去显示和解析,要不断的去判断增长逻辑,效率很是低。如如下伪代码解析。
      • 二进制解析:解析起来就比纯文本更加方便。如如下伪代码的解析。代码量少,更加方便
      • http/2把原来的"Header+Body"的消息"打散"为数个小片的二进制"帧"(Frame),用"HEADERS"帧存放头数据、"DATA"帧存放实体数据。HTTP/2数据分帧后"Header+Body"的报文结构就彻底消失了,协议看到的只是一个个的"碎片"。多个帧之间能够乱序发送,根据帧首部的流标识能够从新组装。
    • (2)、多路复用
      • http1.1的时候,为了解决这个方法,是将同一页面的资源分散到不一样域名下,提高链接上限,Chrome有个机制,对于同一个域名,默认容许同时创建 6 个 TCP持久链接,使用持久链接时,虽然能公用一个TCP管道,可是在一个管道中同一时刻只能处理一个请求,在当前的请求没有结束以前,其余的请求只能处于阻塞状态。另外若是在同一个域名下同时有10个请求发生,那么其中4个请求会进入排队等待状态,直至进行中的请求完成。
      • 多路复用很好的解决了浏览器限制同一个域名下的请求数量的问题,同时也更容易实现全速传输,毕竟新开一个 TCP 链接都须要慢慢提高传输速度。
      • 效果以下:
      • 传输的原理:http/2中同域名下全部通讯都在单个链接上完成。单个链接能够承载任意数量的双向数据流。数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间能够乱序发送,由于根据帧首部的流标识能够从新组装。
    • (3)、头部压缩
      • 经过Hapck算法,在客户端和服务器两端创建“字典”,经过索引去除重复请求,查找压缩方案。
      • 使用霍夫曼编码,能接近gzip的压缩率,也能压缩字符串
      • 例以下图中的两个请求,请求一发送了全部的头部字段,第二个请求则只须要发送差别数据,这样能够减小冗余数据,下降开销
    • (4)、服务器推送(Server push)
      • 在 HTTP/2.0 中,服务器能够向客户发送请求以外的内容,好比正在请求一个页面时,服务器会把页面相关的 logo,CSS等文件直接推送到客户端,而不会等到请求来的时候再发送,由于服务器认为客户端会用到这些东西。这至关于在一个 HTML 文档内集合了全部的资源。以下图所示:
      • 服务端能够主动推送,客户端也有权利选择是否接收。若是服务端推送的资源已经被浏览器缓存过,浏览器能够经过发送RST_STREAM帧来拒收。主动推送也遵照同源策略,换句话说,服务器不能随便将第三方资源推送给客户端,而必须是通过双方确认才行。
    • (5)、加密传输
      • 由于主流的浏览器Chrome、Firefox等都公开宣布只支持加密的HTTP/2,因此“事实上”的HTTP/2是加密的。也就是说,互联网上一般所能见到的HTTP/2都是使用"https”协议名,跑在TLS上面。HTTP/2协议定义了两个字符串标识
    • (6)、优先级
      等等
  • 三、http2时代和http1不一样的优化方法:
    • (1)、http1使用Spriting合并多张小图为一张大图,再用JavaScript或者CSS将小图从新“切割”出来的技术。在http2由于多路复用的应用就不须要这么作了。
    • (2)、http1.1时代使用内联(Inlining)去防止发送不少小图请求的技巧,将图片的原始数据嵌入在CSS文件里面的URL里,减小网络请求次数。
    • (3)、在http1.1时代要拼接(Concatenation)将多个体积较小的JavaScript使用webpack等工具打包成1个体积更大的JavaScript文件,但若是其中1个文件的改动就会致使大量数据被从新下载多个文件。,在http/2时代也不须要这么作,能够分不少js文件去加载。
    • (4)、http1.1时代使用多域名去实现假并行提升传输效率,在http2时代就不须要使用多域名,一个域名创建tcp链接后就能够多路复用去传输。

3、http2存在的问题

  • 一、HTTP/2都是基于TCP去实现的,可是当数据发生丢包的时候会发生阻塞(即tcp hol Blocking)进行数据重传,继而触发“拥塞发生”,其拥塞窗口降为1,在未收到ack以前其余包阻塞。以下图所示:
  • 二、在弱网状况下,频繁丢包,http2的多路复用反而比http1更低效。由于TCP为了保证可靠传输,有个特别的“丢包重传”机制,丢失的包必需要等待从新传输确认,HTTP/2出现丢包时,整个 TCP 都要开始等待重传,那么就会阻塞该TCP链接中的全部请求。而对于 HTTP/1.1 来讲,能够开启多个 TCP 链接,出现这种状况反倒只会影响其中一个链接,剩余的 TCP 链接还能够正常传输数据。
    • http2弱网络测试
  • 三、tcp链接时先要进行3次握手来确认链接成功,也就是须要至少消耗1.5个RTT才能进行数据传输。
  • 四、使用https时,还须要TLS协议进行安全传输,使用TLS也须要一个握手过程。TLS有2个版本,TLS1.2和TLS1.3,每一个版本创建链接所花的时间也不一样,大体须要1~2个RTT。SSL进行中,要进行公钥和私钥传输,以下图:

4、QUIC的介绍和使用

Google设计了一种新的协议QUIC,让HTTP跑在UDP上而不是TCP上。webpack

  • (1)定义:QUIC(Quick UDP Internet connections)快速udp网络链接,由谷歌发明的。顾名思义,是基于UDP作传输层,而与以前的tcp作传输层有区别。
  • (2)原理:使用UDP实现一个可靠的多路复用传输层。UDP是面向数据报文的,数据包之间没有阻塞约束,QUIC就是利用这个特性解决传输层的对头阻塞问题。
  • (3)功能
    • 【1】引入了相似HTTP/2的“流”和“多路复用”,单个“流"是有序的,可能会由于丢包而阻塞,但其余“流”不会受到影响,完全解决TCP中队头阻塞的问题。 nginx

    • 【2】实现了相似TCP的流量控制、传输可靠性的功能,QUIC在UDP的基础之上增长了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其余一些TCP中存在的特性。如下是TCP、UDP和QUIC的区分: web

    • 【3】实现了快速握手功能: 0 Rtt算法

      • 使用UDP规避了三次握手
      • 使用DH加密来规避TLS交互
      • 首包就能够发送数据
      • 并且有1次Server Config的缓存,后面只要缓存不失效,重连也无需TLS交互。
    • 【4】可靠性:chrome

      • 方法:
        • (1)、单调递增seq
        • (2)、单向冗余纠错(异或)
        • (3)、失败重传进行处理
      • 当发生丢包时
        • (1)、尝试使用前向纠错来修复
        • (2)、不能fec,则失败重传。

      举个例子:当发送数据A和B,增长发送1个数据C等于A和B的异或,接收方接到这3个包的任意2个包,异或1下就能够获得第3个包浏览器

    • 【5】、quic拥塞窗口:缓存

      • 实现了tcp的Cubic和NewReno算法
      • 默认采用Cubic
      • nack机制,由接收端告知哪几个包丢失
      • Tail Loss Probes更及时的重传
    • 【6】、其余安全

      • 链接性:使用connection id来识别从新链接的请求
      • 流量控制:能够针对链接控制,也能够对具体的stream id进行控制
  • (3)优点:
    • 【1】、效率高,传输快
    • 【2】、谷歌调优后的QUIC更是重建了可靠性和有序性,但减小了链接次数,尤为是对于加密链接来讲,可以使用先前协商过的相同加密恢复旧链接,而不须要任何额外的往返。
    • 【3】、QUIC 能够实现可靠传输,并且相比于 TCP,它的流控功能在用户空间而不在内核空间,那么使用者就 不受限于 CUBIC 或是 BBR,而是能够自由选择,甚至根据应用场景自由调整优化。
  • (4)quic支持情况:
    • 运营商:udp降级,在国内部分地区的运营商都会针对 UDP 协议QOS限速或者丢包,这就致使 UDP 效率低下,或许速度会比正常使用TCP协议还慢不少。
    • chrome支持:经过chrome://flags/#enable-quic控制,显示quic的协议,看到Experimental QUIC protocol改为enabled,重启浏览器就能够看到,不过要这个网站支持quic才行。
    • nginx暂不支持

5、迎接http3的来临

QUIC 基于 UDP 实现,是 HTTP/3 中的底层支撑协议,该协议基于 UDP,又取了 TCP 中的精华,实现了即快又可靠的协议。也许http3普及以后,如今不少作的性能优化操做就不须要了。 性能优化

相关文章
相关标签/搜索