HTTP/1.1 的限制:Head-of-line Blocking
HTTP/1.1(1997)的主要問題是:同一個 TCP 連線裡,request 必須按順序等待回應。GET /image1.jpg 送出後,必須等 response 回來,才能送 GET /image2.jpg。
解法是瀏覽器同時開多個 TCP 連線(通常 6 個),但每個連線有自己的握手開銷,而且多連線會佔用伺服器資源。
HTTP/2(2015):多路復用
HTTP/2 的核心改進:
Multiplexing(多路復用):一個 TCP 連線裡同時傳多個 request / response(每個是獨立的 stream),不需要等前一個完成。消除了 HTTP/1.1 的 head-of-line blocking。
Header Compression(HPACK):HTTP 的 header 很多是重複的(每個請求都帶 User-Agent、Accept-Language 等),HPACK 壓縮這些重複 header,減少頻寬。
Server Push:server 可以主動推送 client 還沒請求的資源(如 HTML 解析後會用到的 CSS / JS)。實際上很少用,Chrome 已移除支援。
Binary Protocol:HTTP/1.1 是文字協議,HTTP/2 是二進位幀(frame),更高效但沒有可讀性。
HTTP/2 還有什麼限制:TCP 的 Head-of-line Blocking
HTTP/2 的多路復用在應用層解決了問題,但 TCP 層仍然有 head-of-line blocking——如果一個 TCP packet 遺失,所有的 stream 都要等那個 packet 被重傳,即使其他 stream 的資料已經到了。
在不穩定的網路(如 Mobile、衛星網路)上,這個問題很明顯。
HTTP/3 / QUIC(2022):換掉 TCP
HTTP/3 把 TCP 換成 QUIC(Quick UDP Internet Connections)。QUIC 基於 UDP,但在應用層實作了可靠傳輸——和 TCP 不同,QUIC 的 stream 是真正獨立的,一個 stream 的 packet loss 不影響其他 stream。
QUIC 的改進:
- 真正的多路復用:stream 之間無阻塞
- 0-RTT 連線建立:對已知的 server,第一個資料包可以帶著握手資訊——從 TCP + TLS 的 3 RTT 降到 0 RTT
- Connection Migration:手機從 WiFi 切到 4G,QUIC 連線可以繼續(不需要重新握手),因為 QUIC 的 connection ID 不跟 IP 綁定
你需要做什麼
HTTP/2:現代 nginx / Caddy / cloud load balancer 預設支援,通常不需要做什麼特別的事,只要你的 server 有 HTTPS 就行。
HTTP/3:主要 CDN(Cloudflare、Fastly)和瀏覽器都已支援。用 CDN 就能自動獲得 HTTP/3 的好處,不需要自己維護 QUIC server。
深入的 QUIC 運維在 infra/network-edge I01 章節。