HTTP1.0到3.0浅析

HTTP 1.0

  • 每个对象连接时间:2 * RTT (Round Trip Time) + L/R,即TCP连接建立时间 + HTTP从请求到响应的前几个字节返回的时间 + 对象或者文件传输的时间。
  • 后续多个对象,通过对象文件的并行连接,实现同时多个对象传输。

HTTP 1.1

  • TPC 连接持久化,因此,n 个对象总共传输消耗:RTT + n * (RTT + L/R) 时间。优化了非并行传输时,HTTP 1.0 的 n * (2 * RTT + L/R)。
  • 流水线优化后,服务器连续不断地发送 n 个对象文件,而不需要每个对象再次请求连接。即,2 * RTT + L/R + RTT + (n - 1) * L/R = 3 * RTT + n * L/R。

HTTP 1.1 的问题

  • 服务器按序响应这些请求。如果先处理大对象,那么后续对象会收到影响。
  • 流水线中,由于按顺序处理,如果出现问题,那么后续对象文件传输会出现问题。

HTTP 2.0

  • 服务端增加了向客户端发送对象的灵活性(RFC 7540)
  • 所用方法、状态码、大部分头部字段都和 HTTP1.1 无异
  • 被请求对象传输次序,会基于客户端指定的优先级
  • 将对象切割为 frames ,调度这些 frames 的传输次序,来缓解传输的阻塞问题(HOL),在大对象传输帧时,调度小对象帧同时传输
  • 可以先向客户端推送一些可能会需要的对象,即使还未请求
  • 支持二进制编码,效率更高
  • 支持头部压缩,减少传输数据量

HTTP 2.0 的改进目标就是减少请求的延时。

HTTP 2.0 的问题

  • HOL 阻塞问题仍然存在,仍然在恢复丢失的段数据时,仍然会停止后续对象的传输
  • 可用通过并行连接,增加总体吞吐量,但是增加了服务器负担
  • 没有解决安全问题
  • 结合 TLS,会增加一个 RTT 通信时间,但是 HOL 阻塞仍然存在
  • HTTP 慢启动问题
  • 基于丢失的拥塞控制吞吐抖动
  • 要实现可靠传输,其恢复时间较长,效率低
  • IP 地址变化,TCP 连接无法维持,移动性支持不好
  • TCP 序号二义性,在计算 RTO (Retransmission Timeout) 时,取相同序号包中的哪一个进行计算

问题的根源在于 TCP。一个对策是基于 UDP 实现新的传输协议,比如 QUIC。

HTTP 3.0

将应用层 HTTP 2.0 中一些好的功能转移到一个单独的层 QUIC 上。

  • 多路复用,同时传输多个对象
  • 对象分帧交错传输
  • 使用优先级定义传输次序
  • 二进制传输
  • 头部压缩

将 TCP 的部分功能转移到 QUIC:

  • 流量控制和拥塞控制
  • 基于 UDP 重新高效实现
  • 避免TCP 序号二义性问题,RTO 计算问题

基于 UDP 可以实现连接迁移,因为 UDP 是无连接的。

借助成熟的 TLS 1.3 协议,进行握手认证和交换密钥,使用 QUIC 传输报文。

QUIC 是在应用层中实现,便于部署推广

HTTP3.0 实现。

QUIC 协议之上的 HTTP 2.0。

QUIC

  • 连接: C 到 S 两端节点间的一个会话。每个端点自己选择 connection id,用对方的 connection id 标识一个对端连接。
  • 流(stream): 一个完整的请求和响应的字节流。一个连接上,有多个对象的请求和响应,每个对象的请求和响应在一个流中。 stream id 由 62 位表示,最低两位中一位表示单双向,一位标识流的发起者。
  • 一个连接上,可以有多个流,可以是单向或者双向。
  • frame : 流中数据的单位,分为数据帧和控制帧。
  • 分组 : 连续传输的数据单位,UDP 数据报载荷中有若干分组,分组包含了若干帧。

快速握手

DH 算法实现 0 RTT

连接迁移实现

  • 基于 UDP,OS 内核不维护和对方通信的状态,IP 地址允许变化
  • QUIC 连接在用户态,使用 CID (connection) 维护和对方的通信状态
  • 连接双方各自维护着:CID <=> IP 地址 + UDP 端口,两者之间的对应关系
  • 允许 IP 地址变化或者 UDP 端口变化,只要 CID 不变,那么通信关系仍然维持

拥塞控制和流量控制

  • 可插拔的模块化拥塞控制:默认使用 New Reno 和 Cubic 算法

  • 可以采用新的拥塞控制算法:BBR 、BBRv2 这种

  • 流量控制分为:连接级别,流级别

可靠性传输

  • 高效实现可靠性传输
    • ACK 帧支持最多 256 个 SACK ,而 TCP 最多支持 3 个,可以精确标记接收端哪些分组收到
    • 能避免 99% 以上的超时重传
    • 发送方减少盲目重传
  • PN 单调递增,解决了序号二义性问题
    • 规定 PN(Packet Number) 单调递增。重传分组具有不同的 PN ,但是分组内可能是之前丢失的帧,具备相同的帧号
    • RTO 计算无二义性
  • 超时重传
    • ACK 帧中给出了处理时间,RTO 计算将扣除在接收方的处理时间

头部压缩

  • QUIC-QPACK 采用动态表、静态表等编码方式,减少头部信息传输的数量

服务器主动推送

  • 当服务器收到资源请求响应时,将客户端可能需要的资源主动推送给客户端
  • 设置 Frame Type 为 PUSH_PROMISE

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!