HTTP 2

未来已来

Posted on December 1, 2016

各种技术总会在我们不经意间闯入我们的工作,更新我们的生活,与其措手不及不如提早部署,只有心怀远方我们才能走的更远

历史


  • HTTP/1.0 默认短连接

    不足: 短连接效率低, 每个http事务需要独立的tcp通信

  • HTTP/1.0 尝试使用Connection: Keep-alive 支持长连接, HTTP/1.1 默认开启长连接

    不足: HTTP/1.x 多次请求必须严格满足先进先出(FIFO)的队列顺序, 每个 TCP 连接上只能同时有一个请求/响应。这样一来,服务器在完成请求开始回传到收到下一个请求之间的时间段处于空闲状态. 相当于是串行请求

  • HTTP/1.0 提供基于长连接的管道技术

    不足: 仅解决了客户端可以并发请求, 但是服务端还是必须串行发送响应. 可能造成队首阻塞

    另外管道技术也没有流行起来

  • 采用多tcp通信

    不足: 浏览器同域TCP有限制, 限制的原因就是tpc的资源消耗.

  • 于是HTTP2诞生了(前身是SPDY)


HTTP 2 特性


二进制分帧层(Binary Framing Layer)

  • 在TCP, TLS层上面, http2增加了一层 Binary Framing层

  • 原来HTTP/1.1的文本协议(起始行、首部、实体正文) 被分隔为更小的帧(起始行、首部被分割到 HEADERS 帧, 实体正文被分割到 DATA 帧)

帧 Frame

  • HTTP/2 通信的最小单位,二进制, HTTP/2 规范一共规定了 10 种不同的帧, 其中最基础的两种分别对应于 HTTP/1.1 的 DATA 帧 和 HEADERS 帧

  • DATA 帧有长度的控制(2的14次方-1 字节,约 16383 个字节),应用数据过大时,会被拆分成多个 DATA 帧


多向请求与响应(多路复用)

  • 一个http2连接中多个Stream, 可以并行发送消息, 消息分帧, 帧带有Stream ID, 用于标识和组装消息

流 Stream

  • 已建立的连接上的双向字节流, 一个http2连接同时可以有多个并行的stream, stream中的frame通过Stream ID标识

消息

  • 与逻辑消息对应的完整的一系列数据帧

优先级和依赖性

TODO


首部压缩

在服务器和客户端各维护一个“首部表”,表中用索引代表首部名,或者首部键 - 值对,上一次发送两端都会记住已发送过哪些首部,下一次发送只需要传输差异的数据,相同的数据直接用索引表示即可

TODO 首部针对一次http2事务吗


服务器推送(server Push)

服务器可以对一个客户端请求发送多个响应。也就是说,除了对最初请求的响应外,服务器还可以额外向客户端推送资源

典型场景就是, 服务器在返回html时, 同时直接返回其中需要的css, js

  • 服务器推送的帧类型是PUSH_PROMISE, 是一个类似通知帧, 后续还需要data帧承载具体数据

  • 对于PUSH_PROMISE 客户端可以选择缓存这个资源,也可以拒绝这个资源

    如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送 RST_STREAM 帧来拒收

  • 服务器必须遵循请求-响应的循环,只能借着请求的响应来推送资源

  • 这个过程有点类似于我们常用的资源内嵌的手段

    但内嵌资源是无法被单独缓存的,而服务器推送的资源是可以被缓存的


其他

  • 虽然规格没有强迫使用 TLS实现HTTP/2支持,目前浏览器开发商在实现HTTP/2支持时都是经过TLS, Firefox 和Chrome开发团队的成员明确表示他们只实现使用TLS的HTTP/2

参考