跳转到内容

HTTP/1.1、HTTP/2 与 HTTP/3

HTTP 的三代演进都在解决同一个问题:一条连接上的请求/响应模型太浪费。本章讲持久连接、HTTP/2 的多路复用与头部压缩、HTTP/3 基于 QUIC 的消除队头阻塞,以及缓存控制与 REST 的约束。

HTTP 是无状态的请求/响应协议:客户端发请求(方法、路径、头),服务器回响应(状态码、头、体)。无状态(每个请求独立)让水平扩展容易(→ 系统设计工具箱),会话状态交给 Cookie 与令牌(→ 认证与授权)。

  • HTTP/1.0:每个请求一条 TCP 连接——三次握手 + 慢启动(→ 传输层:TCP 与 UDP)每个请求都付一遍,浪费;
  • HTTP/1.1:**持久连接(keep-alive)**复用连接 + **管线化(pipelining)**连续发请求——但响应必须按序返回,队头阻塞让管线化形同虚设。浏览器的实际解法:每域名 6 条并行连接——把队头阻塞摊薄到 6 条线。

同一个 TCP 连接上多路复用多个流:帧化(二进制分帧)、流优先级、头部压缩(HPACK)——1.1 时代每个请求重复发几百字节的头,2.0 用字典 + 增量编码压缩到几十字节。

HTTP/2 的多路复用仍受 TCP 队头阻塞:所有流共享一条 TCP 连接,一个 TCP 包丢了,所有流都要等重传(→ 传输层:TCP 与 UDP)。2.0 在丢包严重的网络上可能比 1.1 的 6 条连接更慢。

HTTP/3 = HTTP over QUIC:每个流独立重传,流间不再互相阻塞;握手与 TLS 合并(1-RTT 甚至 0-RTT);连接迁移(换网络不断线)。HTTP/3 在丢包网络上优势明显;良好网络上与 H2 差距小(拥塞控制相同)。

HTTP/1.1HTTP/2HTTP/3
连接每域名 6 条1 条1 条(QUIC/UDP)
多路复用无(队头阻塞)有(TCP 队头阻塞)有(流独立)
头部明文重复HPACK 压缩QPACK 压缩
传输TCPTCPQUIC(UDP)

缓存头是性能优化的第一杠杆——最快的请求是不发生的请求:

  • 强缓存:Cache-Control: max-age=3600(新鲜期内不发请求);immutable(永不变化的内容,如带哈希的静态资源);
  • 协商缓存:ETag / If-None-Match、Last-Modified / If-Modified-Since——过期后问服务器"变了吗",没变回 304(不带体);
  • CDN:边缘缓存(→ 系统设计工具箱),Cache-Control: s-maxage 控制边缘,Vary 控制键。

静态资源的标准模式:文件名带内容哈希 + immutable 长缓存——变更即改名,缓存永不失效。

REST 是一组架构约束,不是协议:无状态、统一接口(资源的名词 + 方法的动词:GET/POST/PUT/DELETE)、可缓存、分层系统。回报是可扩展性与缓存友好;代价是"动作丰富的业务"塞进 CRUD 的别扭(用子资源与状态机表达)。GraphQL 与 RPC 是替代路线:前者按需取数(解决过度/不足取数),后者按动作建模——选择看接口的消费方是谁。

  • HTTP/1.1 用 6 条并行连接摊薄队头阻塞;HTTP/2 的多路复用仍受 TCP 队头阻塞
  • HTTP/3 基于 QUIC 消除队头阻塞,丢包网络上优势明显;握手与 TLS 合并
  • HPACK/QPACK 头部压缩:从每请求几百字节到几十字节
  • 缓存头是性能优化的第一杠杆:强缓存(max-age/immutable)+ 协商缓存(ETag/304)
  • 静态资源模式:文件名带哈希 + immutable;REST 的回报是可扩展与缓存友好