Dawn's Blogs

分享技术 记录成长

0%

Triple协议 (2) HTTP2协议

gRPC 仅支持 HTTP 2 协议,而 Triple 协议不仅仅支持 HTTP 2,还支持 HTTP 1,下面介绍 HTTP 2 协议。

为什么提出 HTTP 2

既然已经出现了 HTTP 1.0、 HTTP 1.1,为什么要提出 HTTP 2,这就不得不说一下 HTTP 1.X 的缺陷。

HTTP 1.X 的缺陷

HTTP 1.X 主要有两个缺陷:

  • Header 巨大。
  • 并发能力差。

Header 巨大

每一个 HTTP 1.X 请求和响应都会携带沉重的 Header,这些 Header 严重拖慢传输速度。

并发能力差

尽管从 HTTP 1.0 到 HTTP 1.1 已经做了很多优化,但远远不够:

  • HTTP 1.0:刚开始是非持久连接,一个 TCP 连接只会发出一个 HTTP 请求。后来提出持久连接,但是只能等待上一个请求的响应回来了,才能发出下一个请求;并且持久连接与压缩是冲突的。
  • HTTP 1.1:为了解决持久连接和压缩冲突的问题,提出了分块传输。又提出了 pipeline 模式,允许请求方一口气并发多个请求,但是响应需要按照请求的顺序排列,所以普及率不高。

但是访问一个页面需要发出很多请求(css、js、img 等),如果让请求一个个串行执行,那页面的渲染会变得极慢。于是只能同时创建多个 TCP 连接,实现并发下载数据,快速渲染出页面。这会给浏览器造成较大的资源消耗,电脑会变卡。很多浏览器为了兼顾下载速度和资源消耗,会对同一个域名限制并发的 TCP 连接数量,如 Chrome 是 6 个左右,剩下的请求则需要排队。

为了避开这个数量限制,可以将图片、css、js 等资源放在不同域名下(或者二级域名),避开排队导致的渲染延迟。快速下载的目标实现了,但这会消耗更多的资源,背后都是高昂的带宽、CDN 成本。

HTTP 2 的提出

HTTP 2 的提出就是为了低成本、快速传输,主要做了以下几点:

  • HTTP 2 未改变 HTTP 协议的语义,只是在传输上做了优化。
  • 引入帧、流的概念,在一个域名下只有一个 TCP 连接,借助帧、流可以实现多路复用,降低资源消耗。
  • 引入头部压缩,降低 Header 的空间,提高传输速度。

HTTP 2 特性

HTTP 2 的核心就是头部压缩和多路复用。

头部压缩

提出了 HPACK 2,以索引表(index,Header,Value)的方式进行头部压缩,主要是两种方式:

  • 静态表:高频使用的 Header 制成静态表,静态表是协议级别的约定,是不变的内容
  • 动态表:可以动态的在表中添加 Header 和 Value,添加时可以采用哈夫曼编码,是当前 TCP 连接中协商的结果。

多路复用

HTTP 2 提出了流和帧的概念,每一次请求对应一个流,有一个唯一 ID,用来区分不同的请求;一个流被分成多个帧,这样不同帧根据流 ID 的不同,就可以在一个 TCP 连接上多路复用,多个请求和响应数据穿插在一个 TCP 连接上。

帧类型

HTTP 2 中均以帧进行传输,同时有多种帧的类型,包括:

  • HEADERS:帧仅包含 HTTP Header 信息。
  • DATA:帧包含消息的所有或部分请求数据。
  • PRIORITY:指定分配给流的优先级,服务方可先处理高优先请求。
  • RST_STREAM:错误通知,终止某个流。
  • SETTINGS:指定连接配置。流 ID 为 0,会 ACK。
  • PUSH_PROMISE:通知一个将资源推送到客户端的意图。
  • PING:检测信号和往返时间。流 ID为0,会 ACK。
  • GOAWAY:停止为当前连接生成流的停止通知。
  • WINDOW_UPDATE:用于流控制,约定发送窗口大小。
  • CONTINUATION:用于继续传送 Header 片段序列。

所以一次 HTTP 2 的流程:

  • 通过一个或者多个 SETTINGS 帧配置连接,进行约定。
  • 请求方发送 HEADERS 帧,发送 DATA 帧。
  • 服务方返回 HEADERS 帧,返回 DATA 帧。
  • 。。。