HTTP/1 & HTTP/2

179 阅读3分钟

HTTP/1的问题

截屏2022-12-23 19.37.05.png

解析效率低

http/1.x可以说是一个文本协议,可读性好,但效率不高, 如果要解析一个完整的HTTP/1请求,首先我们需要正确的读出HTTP header,HTTP header各个fields使用\r\n分割,然后跟body之间使用\r\n\r\n分割,解析完header后我们才能从header里面的content-length拿到body的size,从而读取body
这套流程并不高效,因为我们需要读取多次,才能将一个完整的HTTP请求给解析出来,虽然在代码实现上有很多优化方案,比如:

  • 一次将一大块数据读取到buffer里面避免多次IO read
  • 读取的时候直接匹配\r\n的方式流解析

但终归还是有开销的,最主要的问题是http/1更方便给开发者看,但对机器不友好,而http/2的二进制协议对机器更友好

交互限制

http/1的交互模式,一个连接每次只能一答一问,也就是client发送了request之后,必须等到response,才能继续发送下一次请求,而http/2支持长连接,所以可以多次交互

服务器推送不友好

由于http/1没有推送机制,所以通常做法如下:

  • 轮询
  • WebSocket

HTTP/2

http/2是一个二进制协议,这也就是意味着它的可读性几乎为0,但是效率高
http/2所有性能增强的核心在于新的二进制分帧层,它定义了如何封装HTTP消息并且在客户端与服务器之间传输。

截屏2022-12-24 12.29.14.png 这里所谓的层,指的是位于套接字接口与应用可见的高级HTTP API之间一个经过优化的新编码机制,HTTP的语义(包括各种动词、方法、标头)都不受影响,不同的是传输期间对他们的编码方式变了。 HTTP/1协议以换行符作为纯文本的分隔符,而HTTP/2将所有传输的消息分割为更小的消息和帧,并采用二进制格式对它们编码
这样一来,客户端和服务器为了相互理解,都必须使用新得二进制编码机制:http/1客户端无法理解只支持http/2的服务器,反之亦然。

数据流 & 消息 & 帧

  • 数据流Stream:已建立的连接内的恶双向字节流,可以承载一条或者多条消息
  • 消息Message: 与逻辑的请求或者响应消息对应的完整的一系列帧
  • 帧Frame:HTTP/2通信的最小单位,每个帧都包含帧头,至少也会表示出当前帧所属的数据流
    这些概念的关系总结如下:
  • 所有通信都在一个TCP连接上完成,此连接可以承载任意数量的双向数据流
  • 每个数据流都有一个唯一标识符和可选的优先级信息,用于承载双向消息
  • 每条消息都是一条逻辑HTTP消息(例如请求或响应),包含一个或多个帧
  • 帧是最小的通信单位,承载着特定类型的数据,例如HTTP标头、消息负载、等等,来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重新组装 截屏2022-12-24 12.56.39.png

截屏2022-12-24 13.14.35.png

截屏2022-12-24 13.28.00.png