HTTP2的理解

100 阅读2分钟

HTTP1.1的问题

1.req-rsp模型,单个tcp上,必须等上一个http请求返回以后,才能继续发下一个请求。
2.header重复发送,每一个http包,都有大量的header字段,特别是传输文件或者传输大量http包的场景,header浪费了很多的带宽。
3.header没有压缩,http1.1可以在header中指定body采用gzip压缩【http2也支持】,但是头部本身却不支持压缩,而且,大部分场景下,头部都是不少的开销。

HTTP2的优势

1.多个流复用同一个tcp链接,解决了上述的第一个痛点。
2.Hpack+haffman进行header的压缩,解决了上述的第二三个痛点。
3.服务端推送,相当于长连接主动推,但是貌似会有些问题

HTTP2的核心概念

http2规范定义了http共有10种帧格式,分别对应不同的功能 image.png

流 ID 是 31 位无符号整数,客户端发起的流必须是奇数,服务端发起的流必须是偶数。每个流处理自己的帧,多个流互不影响,从而形成了多路复用。【延伸出了应用层滑动窗口的流量控制,流控本身是基于帧来做的,因为流是逻辑上的概念,实际需要传送的数据是在帧里面】

为了方便管理,流有不同的状态,在不同的状态下能处理不同的事情 image.png

头部压缩

image.png

流量控制

tcp协议已经提供了流量控制功能,那么http2在应用层为什么还要提供这个功能?

HTTP/2 的 flow-control window 有两类,stream flow-control window(以下简称 sfw) 和 connection flow-control window(以下简称 cfw)。 一个 connection 可以有多个 stream,每个 stream 都会维护自己的 sfw,然而 cfw 每个 endpoint 只有一个。换句话说,所有 stream 共享一个 cfw。 理解了这一点就好说了。sender(可以是任意一个 endpoint)发送 DATA frame,该 endpoint 的 sfw 和 cfw 都要减掉 frame payload 大小。而由于 cfw 是共享的,总共就那么多(先不考虑 WINDOW_UPDATE),一个 stream 用得多,其它 stream 就用得少。为了保证每个 stream 都能发送数据,当然就需要某种控制策略。

就好比一瓶水很多人要喝,就需要定一个规则确保大家都有水喝。不过 RFC 只规定了『必须有这样一个规则』,具体策略交给实现自己决定。

参考文章:laike9m.com/blog/rfc754…

总结

http2本质上就解决了两个问题,一个是多流复用,提高了tcp连接的利用率。另外一个是头部压缩,和二进制传输,降低的带宽的占用。基于多流复用又产生了一系列流控的规则和算法,其实不需要普通开发关心。

想要了解http2的细节,可以阅读以下文章:www.jianshu.com/p/e57ca4fec…