浅谈HTPP2

687 阅读5分钟

HTTP2是什么


HTTP/2HTTP 网络协议的一个重要版本。 HTTP / 2的主要目标是通过启用完整的请求和响应多路复用来减少 延迟,通过有效压缩HTTP标头字段来最小化协议开销,并增加对请求优先级和服务器推送的支持。

HTTP2的改进

队头压缩


在现在的网站中,每个页面的请求都很多。而每个请求,很多时候会存在头部数据比请求数据好几倍的情况,如我司的请求(下图fiddler抓包),为了请求645字节的数据,请求头和响应头要发送1270+156字节的数据。这样其实造成了极大的浪费。

image.png


而HTTP/2带了头部压缩很有效的解决了这个问题,如我司的同一个请求(下图为wireshark抓包,如何用wireshark抓取HTTP2包可以看另外一篇文章),可以把头部字节长度压缩到548字节。
image.png


那HTTP/2怎么优化头部数据的呢?技术原理主要通过在客户端和服务端之间,通过静态字典、动态字典和基于静态哈夫曼码表的哈夫曼编码来优化。
我们用一次请求来看看其中压缩的原理,如下图所示:

  1. 我们有一次请求,头部字段Request headers如图所示;
  2. 先在静态字典Static table(完整表格在这里)中寻找完全匹配的键值对,把对应的转化为索引值,如:method GET、:scheme https分别转化为2、7
  3. 部分键匹配或部分键值对都不匹配,通过哈夫曼编码后,添加到动态字典Dynamic table中,如user-agent Mozilla/5.0...、:host example.com分别转为62和63;
  4. 部分键匹配或部分键值对都不匹配,只能通过**哈夫曼编码,**但不添加动态字典,如Huffman("/resource"),Huffman("/custom-hdr"),Huffman("/resource");


提示:这里的哪些可以添加到动态字典,具体细节,可以参考:imququ.com/post/header…


多路复用


HTTP/1.1是基于请求-响应模型,意味着后面的请求必须等待前面的请求的返回才能执行,这就叫队头阻塞。而在HTTP/2中,多路复用特性就解决了这个问题,多个请求可以同时在同一个连接中并行执行,两者对比如下图所示。

image.png

更直观的可以看Chrome的Network,下图是我司项目某一页面的请求对比,可以看出在图的右侧中,由于浏览器HTTP/1.1一次只能同时请求6-8个的原因,后面的请求被前面的请求阻塞了,而HTTP/2很好地解决了这个问题。
image.png

那HTTP/2是怎么实现多路复用的呢?

  1. 首先,HTTP/2会把报文全部变成二进制格式的01串,再把原本Headers +  Body 的报文格式分成了一个个的二进制帧,帧头存放头部字段,而帧体存放实体数据,每一个帧组成如下图所示。帧长度指帧体的长度;帧类型指明是当前帧是数据帧还是控制帧,前者存放HTTP报文,后者管理传输;标志位,常用的有END_HEADERS(表示头数据结束)、END_STREAM(表示单方向数据发送结束);流标识符(Stream ID),作为流的唯一标识,接收方能从乱序的二进制帧中选择出 ID 相同的帧,按顺序组装成请求/响应报文。

image.png

  1. 然后再看看传输过程(这个二进制帧的传输我们称为)。我们从最简单的请求-响应看看这个过程(如下图):
    • 开始客户端和服务端都是是空闲状态;
    • 客户端发送Header帧(帧头)后,分配Stream ID,客户端的流主动打开,而服务端收到后流被动打开;
    • 这个时候可以互相传输数据帧和控制帧;
    • 当客户端希望关闭流发送,发送END_STREAM帧来告诉客户端,这时候客户端不再发送,服务端收到后也不再接受;
    • 当服务端希望关闭流发送,发送END_STREAM帧来告诉客户端,这时候服务端完全关闭,客户端也完全关闭。

  1. 正因为有这样的流状态变化过程,一次连接是可以同时发送多个二进制帧,意味着可以同时发送多个请求,只要通过Steam ID重新组合成对应的请求报文和响应报文就可以了。

服务端推送

服务端推送就是通过已开启的连接,服务端可以主动推送资源到客户端。比如比较推荐的标识依赖资源,在我们要请求的HTML文件上写上:

<link rel="preload" href="push.css" as="style">

,服务器收到请求后,在返回HTML的基础上,再推送请求的css,这样就可以减少客户端的访问延时。

HTTP2的使用

  • 在支持方面,常见的服务器都支持了,配置也十分方便,但由于HTTP/2建立在TLS上面,需要网站支持上HTTPS,这个可能需要额外的成本(域名和证书);而在浏览器支持上,除了IE和其他低版本版本浏览器不支持,其他浏览器都无问题的,哪怕浏览器不支持,用户也只会降到HTTP/1.1版本,不会访问不了网站;
  • 在使用方面,对于请求css或js不用再结合在一起,而可以正常分包,多路复用的特性让资源让请求不会阻塞;不用再使用域分片来突破请求数限制;在同一域名下,请求越多,对头部压缩的效率还更高。

参考