从HTTP/1.1到HTTP/2,让WEB性能更上一层楼

从HTTP/1.1到HTTP/2,让WEB性能更上一层楼_第1张图片
http2

HTTP协议是互联网WEB应用的基石,这样定义恐怕没有人会反对吧。但是你可知HTTP1从诞生到现在马上就有20年的历史了,这20年互联网已经发生了翻天覆地的变化,然而HTTP1却一直保持它原有的样子默默无闻的支撑着所有的WEB请求,无数的开发者为了提升HTTP1的性能也开创了很多种优化的方法与实战技能,直到HTTP2的出现我们提升WEB性能的方式也随之发生了变化。这篇文章便从HTTP的历史说起一直到最新的HTTP2。

1、追溯HTTP历史

​ “超文本” 这个词提出是在1963年左右并于1965年首次出现在一名美国软件设计师所发表的文章中。在1989年有了最初的HTTP协议版本也就是0.9版本,现在已经废弃,它只有一个GET方法。在1996年通过了RFC1945制定了HTTP/1.0规范,这是一个很大的进步,这个版本里面已经有我们目前很熟悉的概念了,比如,HTTP首部、响应码、重定向等等。快马加鞭,在1999年便诞生了HTTP/1.1也就是现在我们广泛使用的协议,它比HTTP1.0改进的地方主要有如下几个方面:OPTIONS方法、压缩和传输编码(transfer-encoding)等等。HTTP/1.1定稿之后,它便没有变化也没有任何改进过,截止目前HTTP/1.1版本的协议我们已经即将使用20年了。

2、HTTP1下的优化方法

谈到优化,那么首先看一下影响HTTP性能的指标主要有如下:

1、延迟(我们常说的RTT时间端点之间的往返),

2、带宽,

3、DNS查询,

4、建立连接时间(TCP三次握手),

5、TLS协商时间(HTTPS连接请求下),

6、首字节时间(TTFB,从请求到接收到响应第一字节所耗费的时间),

7、内容下载时间(TTLB),

8、文档加载完成时间,

9、页面复杂度

10、更多的域名,css一个,图片一个,js一个等等。

11、更多的TCP socket ,HTTP/1.1下浏览器客户端会对一个域名开启最多6个socket连接。

另外HTTP/1.1还有几个重要特点:

2.1、队头阻塞

​ 在HTTP/1.1下,如果使用一个连接去请求一个域名下有很多资源,则必须经过发起请求-等等响应-再发起请求这样的过程。在请求应答的过程中,如果出现任何问题包括服务端响应、网络等问题,那么剩下的所有处理都会被阻塞在上次请求应答之后,这就是 “队头阻塞” 问题。即使浏览器客户端会对单个域名开启最多6个socket连接(这个也要跟具体的浏览器来区分比如Firefox是6个,Chrome则是24个)来分发请求,但是每个连接下仍然会受到 “队头阻塞” 的影响。

2.2、拥塞窗口

我们已知HTTP协议之下TCP的支撑,那么TCP成功的关键不是因为它高效而是最可靠的协议之一,这中间有个 “拥塞窗口” 的概念:在接收方确认数据包之前,发送方可以发出的TCP包的数量。比如 拥塞窗口 被指定为1 那么发送方发出1个数据包之后只有接收方确认了这个包,才能发送下一个。那么网络应该怎么才能知道 这个窗口的大小被指定多少合适呢,TCP还有一个概念叫 “慢启动”,形象化的比喻就好比在一间黑暗的屋子,当我们碰到桌子或者凳子的时候就会调整换个方向,慢启动也是这样的原理来调整拥塞窗口的大下。在这样的机制下,比如要发送请求一个大小为2M的HTML页面,在数据包设置为最大值1460字节,拥塞窗口为4,也就是一次发送5840字节的情况下,就需要9次往返才能传输整个页面。可以说HTTP/1.1是低效的利用了TCP。

2.3、臃肿的消息首部

HTTP消息首部被用来描述资源信息,或者是客户端和服务器的行为,自定义专有的首部可以加上 “X-” 前缀。另外cookie也属于消息首部的范畴。在HTTP/1.1中虽然提供gzip压缩机制,但是对于消息首部却无法压缩,虽然这些内容比正常请求的内容资源小的多,但也是不能被忽略的,如果计算上cookie里面的内容,几千个字节是很正常的。尤其是在低带宽或者高拥堵的链路下,就会发生类似 “体育馆效应” 的问题,成千上万人同一时间出现在同一地点,迅速耗尽无线蜂窝网络带宽。这个时候如果能压缩请求首部将其变得更小,那么就能缓解带宽压力,降低系统的总负载。

基于以上我们已知的影响HTTP性能的指标以及我们列出的HTTP/1.1协议下的特点,我们平时都是怎么优化这些网络请求响应的呢。主要有以下几种方法。

1、DNS查询优化

2、优化TCP连接

3、避免重定向

4、客户端缓存

5、压缩和代码极简化

6、避免阻塞 CSS/JS

7、图片优化

在HTTP/1.1这么长的时间里,以上列举出的优化方法大家都已经耳熟能详了。这里不再过多叙述,如果有不了解的可以查阅相关资料,因为它不是这篇文字的重点。

3、认识HTTP2

在2009年,也就是HTTP/1.1协议规范制定10年之后的时间,Google 的工程师提出了HTTP的替代方案 SPDY。如今的HTTP2就是在SPDY的基础上发展起来的。

3.1、HTTP1的传输方式

在HTTP/1.1的环境下是以文本格式传输,解析还原都是以文本分割,比如下面这段内容,读取然后直到遇到分隔符,这里是。这样往往速度比较慢,需要不断读入字节。最重要的一点是所请求的内容需要按照顺序,而且服务端也是按照接受的顺序依次解析响应输出给客户端。这种方式就会带来我们在2.1里面介绍的 队头阻塞 问题。

GET / HTTP/1.1  
Host: www.example.com  
Connection: keep-alive  
Accept: text/html,application/xhtml+xml,application/xml;q=0.9...  
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4)...  
Accept-Encoding: gzip, deflate, sdch  
Accept-Language: en-US,en;q=0.8  
Cookie: pfy_cbc_lb=p-browse-w; customerZipCode=99912|N; ltc=%20;... !

3.2、HTTP2的传输方式

到了HTTP2,数据传输都是以帧为最小单位进行传输,然后由帧再组成流。在网络两端之间交互传输。在HTTP/1.1中的首部信息会被封装到Headers帧,而我们的request body则被封装到Data帧里面。下图是一个HTTP2帧的结构。其中Type为帧的类型,比如有DATA帧,HEADERS帧等等。

从HTTP/1.1到HTTP/2,让WEB性能更上一层楼_第2张图片
HTTP2帧结构(图片选自《HTTP/2基础教程》一书)

3.3、HTTP1和HTTP2请求响应对比

下面这张表左侧表示的是HTTP/1.1请求和响应,右侧是对应的HTTP2下面的请求和响应。这种描述只是展现HTTP2的内容,实际传输的过程中不是这样的。

HTTP/1.1 HTTP2
GET / HTTP/1.1 Host: www.example.com User-agent: Next-Great-h2-browser-1.0.0 Accept-Encoding: compress, gzip HTTP/1.1 200 OK Content-type: text/plain Content-length: 2 ... :scheme: https :method: GET :path: / :authority: www.example.com User-agent: Next-Great-h2-browser-1.0.0 Accept-Encoding: compress, gzip :status: 200 content-type: text/plain

3.4、附两个定义概念:

帧:HTTP2数据通信的最小单位。消息由一个或多个帧组成。

流:“HTTP/2 连接上独立的、双向的帧序列交换。” 你可以将流看作在连接上的一系列帧,它们构成了单独的HTTP请求和响应。每个流都有一个唯一的流标识ID。

4、HTTP2的优势

HTTP2相对于HTTP/1.1有三大特点,分别是多路复用、头部压缩、Server Push。本文章第四部分着重介绍分析多路复用和头部压缩这两个特点下所突出的HTTP2的性能优势,另外我们再介绍HTTP2的反模式的内容。

​4.1、传输优势(多路复用)

根据上面的介绍HTTP2中的数据传输都是以最小单位帧去传输的,对某一个域名所有的请求和响应都在一个TCP连接上完成交互,而且数据没有大小的限制(突破了HTTP/1.1下面的单个包1460字节约1.5K的大小限制),只要带宽足够。而且这些发送的数据帧之间可以乱序,并行交错的请求和响应而且之间互不干扰,然后HTTP2内部再根据帧首部的流标识ID再进行重新组装。交互起来如下图所示:

从HTTP/1.1到HTTP/2,让WEB性能更上一层楼_第3张图片
http2传输

有了这样交错的传输带来的重要影响:

1、可以在一个套接字上交错地发送请求,请求之间互不影响;

2、可以在一个套接字上交错地发送响应,响应之间互不干扰;

所有请求和响应都无法相互阻塞。

3、消除不必要的延迟,从而减少页面加载的时间;

以上也就是常说的HTTP2的多路复用技术,通过客户端与服务端之间的一个socket连接通道,传输的内容不再必须是有序的,可以无序从上图就可以看出来,同时在HTTP/1.1下浏览器客户端受限于并发请求数(同一个域名并发数有限制)的问题也将迎刃而解。

4.2、头部压缩

我们在2.3中已经知道HTTP/1.1下消息首部是不会被压缩的,但是在HTTP/2.2中这点被彻底改变了。利用了HPACK这种压缩的方式大大减少了网络传输过程中首部的体积大小。HPACK的原理可以举例如下。

假设客户端按照如下顺序发送请求首部:

Header1: dog

Header2: pig

Header3: cat

当客户端发起请求的时候,在首部数据块中会通过一张类似关系型数据表的形式存储,指定了首部内容和索引的对应关系,如下:

索引 首部名称
87 Header1 dog
88 Header2 pig
89 Header3 cat

当服务端收到这些请求的时候,也会同样创建一张类似这样的表。客户端发起下一次请求的时候,如果发现首部跟上次相同,此时客户端便可以直接发送首部索引值。如下:

87

88

89

服务器会查找先前的表格并把这些数字还原成索引对应的完整首部内容。HTTP2就是通过这样的方式对消息首部进行压缩的。在这种方式下节省了传输的内容大小提升了请求响应性能。

4.3、反模式

如果将HTTP/1.1时代下那些优化性能的方法称为模式的话,那么这里就出现了一个 “反模式” 的概念,因为在HTTP2的环境下那些方法将不再起作用或者完全没有必要。如下在HTTP/1.1中被使用的方法将都是 反模式 。

1、域名拆分

2、资源内联

3、资源合并

4、禁用cookie的域名

5、生成精灵图片

5、从HTTP1迁移到HTTP2

客户端,目前主流的浏览器已经支持HTTP2,我们以最常用的谷歌、火狐、微软的浏览器为例,下面的表格是他们支持HTTP2的版本信息。

浏览器名称 最低支持版本
Chrome 41
Firefox 36
Internet Explorer 11

服务端,我们以nginx为例,版本需要1.9.5以上。如果所编译的Nginx不支持还需要在 ./configure 中加入 --with-http_v2_module 作为编译参数。配置支持HTTP2主要是配置server块,HTTP2需使用HTTPS,SSL证书的选择可以申请免费的也可以购买。配置示例如下:

server {
listen 443 ssl http2 default_server;
server_name www.testhttp2.com;

ssl_certificate /path/to/public.crt;
ssl_certificate_key /path/to/private.key;

总结

自从1999年HTTP/1.1发布后,HTTP2是HTTP发布的首个更新。二十年的互联网江湖里,浮浮沉沉,造就了很多伟大的互联网企业,也倒下了很多曾经的巨人。相对于HTTP1的技术环境HTTP2给我们带来了WEB通讯的诸多优点使得请求响应的性能最大化提升。HTTP2是一个趋势,在未来的技术精进之路上,我们需要拥抱它。使用HTTP2的网站业务理论上完全不受影响,但在迁移之前当然要仔细考虑一些问题。正如《HTTP/2基础教程》这本书中的描述:虽然许多主流网站运行 h2 已经有段时间了,但这并不意味着采用 HTTP/2 会 “稳赢”。对待它应当和对待其他重大变化一样:测试,测试,再测试。

Reference resources:

1、《HTTP/2基础教程》

2、https://httpwg.org/specs/rfc7540.html

声明:原创文章,抄袭必究。转载请标明出处。

你可能感兴趣的:(从HTTP/1.1到HTTP/2,让WEB性能更上一层楼)