← 返回题目列表

TCP 队头阻塞是什么?它和 HTTP/2、QUIC 的队头阻塞有什么区别?

中等 第 25 / 30 题 更新于 2026/08/01
TCP队头阻塞HTTP2QUIC

简化版

TCP 队头阻塞指的是:TCP 必须按序向应用层交付字节,如果前面的一个报文段丢失,后面即使已经到达,也要等缺失部分重传后才能交付。HTTP/2 在一个 TCP 连接上复用多个流,所以底层 TCP 丢包会阻塞所有流;QUIC 基于 UDP 在应用层实现多流可靠传输,可以让一个流丢包不阻塞其他流。

详细版

TCP 的可靠有序交付让应用层看到的是连续字节流:

已收到: segment 1, segment 3, segment 4
丢失: segment 2
应用层只能拿到 segment 1
segment 3/4 必须等 segment 2 补齐后才能交付

HTTP/2 解决了 HTTP/1.1 应用层请求排队问题,但仍受 TCP 层队头阻塞影响。QUIC 把多路复用放到传输层之上,流之间可以独立排序和重传,因此缓解 TCP 丢包导致的跨流阻塞。

完整版教学

一、TCP 为什么必须按序交付

TCP 对应用层承诺的是可靠、有序的字节流。应用调用 read 时,不应该看到中间缺洞的数据。

字节 0..999 已收到
字节 1000..1999 丢失
字节 2000..2999 已收到

应用最多只能读到 999,后面的字节要等缺失区间补齐。

二、队头阻塞发生在哪里

队头阻塞本质是“前面的东西没准备好,后面的东西不能越过它”。

层次阻塞原因
TCP 层前面字节缺失,后续字节不能交付
HTTP/1.1同连接内前一个响应没完,后一个响应排队
HTTP/2 over TCP多流复用,但 TCP 丢包会阻塞整个连接
QUIC单个流丢包只阻塞该流

面试抓手:HTTP/2 解决的是应用层队头阻塞,但没有消除 TCP 层队头阻塞。

三、HTTP/2 为什么仍会被 TCP 丢包影响

HTTP/2 把多个请求响应复用到一个 TCP 连接里,帧可以交错发送。但这些帧最终仍是 TCP 字节流的一部分。

如果 TCP 字节流中某个包丢了,后面到达的 HTTP/2 帧虽然可能属于其他流,也不能越过缺口交给 HTTP/2 层处理。

TCP 缺字节
HTTP/2 解帧被卡
所有复用流都受影响

四、QUIC 如何缓解

QUIC 基于 UDP,在用户态实现可靠传输和多路复用。它的流有独立的偏移和重传逻辑。

Stream A 丢包:A 等重传
Stream B 数据完整:B 可继续交付

因此 QUIC 能缓解 TCP 丢包导致的连接级队头阻塞。

五、队头阻塞不等于吞吐一定低

TCP 的按序交付让编程模型简单,也保证字节流语义。队头阻塞在丢包、弱网、高并发复用场景更明显;在稳定网络里影响可能不突出。

优化要看丢包率、RTT、连接复用程度和业务延迟目标。

六、如何定位

可以通过抓包和指标观察:

TCP 重传增多
应用层延迟尖刺
HTTP/2 多个 stream 同时变慢
QUIC 迁移后同样丢包下尾延迟改善

但队头阻塞只是网络尾延迟的一种来源,不能替代完整排障。

七、常见误区与追问

  • 误区:HTTP/2 完全解决了队头阻塞。 它解决应用层复用排队,仍受 TCP 丢包影响。
  • 误区:TCP 收到后面的包就能交给应用。 TCP 必须按序交付连续字节流。
  • 误区:QUIC 没有任何阻塞。 单个 QUIC 流内部仍需要按序交付。
  • 追问:TCP 队头阻塞的根因是什么? 可靠有序字节流要求不能越过缺失字节。
  • 追问:为什么 HTTP/2 多流会一起受影响? 多个流共享同一条 TCP 字节流。
  • 追问:QUIC 怎么缓解? 在传输层实现独立流,丢包只阻塞相关流。

八、加强记忆

TCP 队头阻塞来自“前面的字节没到,后面的字节不能交”。HTTP/2 只是把多个流塞进同一条 TCP,底层缺一个包仍会卡全部;QUIC 把流独立出来,所以一个流丢包不拖住所有流。