Skip to content

队头阻塞

不同版本的 http 都有 队头阻塞 问题,不同版本的队头阻塞都不相同

http 1.1

http 1.1 引入持久连接和流水线传输功能,允许单个 tcp 连接上同时发送多个请求

虽然可以同时发送多个请求,但是服务器只有处理完一个 response 才会处理下一个,如果某一个 response 耗时很长,后续响应都需要等待,这就是 http 1.1 中的队头阻塞,发生在应用层

http 2

http 2 引入多路复用和帧、流(一个流就是一个请求或响应)的概念,并且只有一条 tcp 连接,服务器同时发送的多个帧,可以不是同一个流,具体如何发送流,由 "http 2" 的优先级系统驱动

虽然 http 2 解决了 http 1.1 的队头阻塞,但这也只是解决了应用层阻塞的问题,在传输层 tcp 中,如果出现了丢包,同样会阻塞 http

tcp 协议传输字节流,使用滑动窗口(Sliding Window)机制来实现流量控制和拥塞控制,当出现丢包时,滑动窗口不移动,需要重新传输丢失数据包的副本,滑动窗口中已经到达的tcp包会等待未到达的包

试想当前一共有2个 http 2 流,流id 分别是 stream1、stream2,tcp 在传输过程中丢了一包数据,刚好这一包数据是 stream2,从 http 2 的视角来看,stream1 已经全部达到传输层应该 push 给 http,但对于 tcp 协议,他并不知道 stream1 stream2 有什么区别,都是非透明的字节流,当前滑动窗口出现丢包,那大家都别走,等一等重新传输再一起走,这样 tcp 传输层的队头阻塞就会传导到应用层导致 http 阻塞

TIP

优先级系统驱动

  • 公平多路复用(例如两个渐进的 JPEGs):12121212
  • 加权多路复用(2是1的两倍):22122122121
  • 反向顺序调度(例如2是密钥服务器推送的资源):22221111
  • 部分调度(流1被中止且未完整发送):112222

http 3

TTP/3 是基于 QUIC 协议的下一代 HTTP 协议。QUIC(Quick UDP Internet Connections)是一种基于 UDP 的传输协议

QUIC 受到 HTTP/2 帧方式(framing-approach)的启发,还添加了自己的帧(frames);在本例中是流帧(STREAM frame)。流id(stream id)以前在 HTTP/2 的数据帧(DATA frame)中,现在被下移到传输层的 QUIC 流帧(STREAM frame)中。(这也说明了如果我们想使用 QUIC,我们需要一个新版本的 HTTP 的原因之一)

http3

TIP

因为 http 3 将流、帧下放到了 QUIC 协议中,所有 QUIC 能够识别到流、帧,在发生某一个流丢包时,不相关的流继续传输不会阻塞