HTTP/1.1 的队头阻塞问题是什么?
HTTP/1.1 的队头阻塞问题由请求按顺序处理引起,导致后续请求响应延迟。解决方案包括使用多个 TCP 连接和域名分片。
HTTP/1.1 的队头阻塞问题是指当一个 TCP 连接上维护多个请求的复用机制导致首个请求处理变慢时,后续所有请求都无法及时接收响应的现象,主要由于 HTTP/1.1 协议的管道化(pipelining)特性限制造成:
- 根本原因与机制
- HTTP/1.1 支持复用持久连接,但由于其明文协议特征,请求和响应需按严格顺序处理,不能并行处理或混合顺序。如果客户端同时启用多个连接或同一域名下允许多个请求加入连接(即管道化),请求能被批量发送但响应仍须依发送顺序严格返回。例如,如果一个资源响应被延迟接收(如下载延迟),后续关联资源的响应就被强制性阻塞无法获取。
- 服务器逻辑处理中必须按照 HTTP/1.1 的要求按照写入时顺序处理与响应写入到连接之中。在连接复用中不能做到中断前请求去响应别的请求请求。
- 性能影响
- 此特性阻碍 web 加载效能,使重要资源不能提前返回影响视觉可见用户。页面延迟明显恶化用户的首次页面启动时间指标(FCP),特别是在高资源数的现代单页应用(SPA)中明显可测试观察到响应时间异常。
- 当前在 HTTP/1.1 层面的解决措施
为适应 HTTP/1.1 无法有效解决此问题而提出下列解决方法:- 并发 TCP 连接(Concurrent Connections): 浏览器自身行为绕过序问题允许单一域名可以允许多个 TCP 连接被发起并行处理。如 Chrome默认一次启动6个,不同浏览器支持不同数:
// Chrome 中的连接限制数默认为6,可在 network panel 验证。
增加并行处理有效减少队头问题。
- 域名分片法(Domain Sharding):通过多个子域名处理,服务器接受分多域请求实现并行下载资源。若一个域名如
example.com
,可拆分至三个或多像static1.example.com
、static2.example.com
, DNS指向同一服务器并分散载图资源请求:// 代码示例,用域名分散资源请求地址 <img src="https://cdn1.site.com/img.png" alt="Image 1"> <img src="https://cdn2.site.com/img.png" alt="Image 2">
- 并发 TCP 连接(Concurrent Connections): 浏览器自身行为绕过序问题允许单一域名可以允许多个 TCP 连接被发起并行处理。如 Chrome默认一次启动6个,不同浏览器支持不同数:
- HTTP/2 / HTTP/3 的针对性替代手段与延续解法
- HTTP/2 引入数据层传输架构使一TCP连接多复用资源块帧(frames)分别对应不同流标识符发送请求数据分割方式处理,各分针交错重新排序列处理解决 HTTP request层级堵塞 方法为:
请求发送模型如下: 客户端发送 => Frame[Stream ID=1], Frame[Stream ID=2], ... 服务器返回 => 帧根据其 ID 组成所需响应
底层 TCP 数据段若乱序丢失影响帧重新组序列时可能让阻塞延迟在 TCP 维度重现即所谓 TCP 层级队头阻塞 (TCP Head-of-Line Blocking)仍无法解决。
- 引入 HTTP/3协议利用 QUIC UDP协议来完全规避类似 TCP段结构导致的序列和确认延迟,使帧可脱离传输队首瓶颈。
- HTTP/2 引入数据层传输架构使一TCP连接多复用资源块帧(frames)分别对应不同流标识符发送请求数据分割方式处理,各分针交错重新排序列处理解决 HTTP request层级堵塞 方法为: