跳转至

域名分片(Domain Sharding)

HTTP/1.1 时代的聪明 hack——用多个子域名骗浏览器多开连接,绕过同域名 6 连接限制


核心概念

  1. 浏览器连接限制 — 同一域名最多同时开 6 个 TCP 连接
  2. 域名分片 — 用多个子域名指向同一服务器,每个域名都能开 6 个连接
  3. 缓存碎片化 — 不同域名的缓存独立,可能重复下载相同资源
  4. HTTP/2 淘汰 — 多路复用从根本上解决了这个问题,域名分片已无必要

详解

它要解决什么问题

浏览器对**同一域名**最多同时开 6 个 TCP 连接,这是硬限制。一个页面要加载 30 个资源:

只用一个域名 www.example.com:

连接1: req1 → req7  → req13 → req19 → req25
连接2: req2 → req8  → req14 → req20 → req26
连接3: req3 → req9  → req15 → req21 → req27
连接4: req4 → req10 → req16 → req22 → req28
连接5: req5 → req11 → req17 → req23 → req29
连接6: req6 → req12 → req18 → req24 → req30

30 个资源 ÷ 6 个连接 = 每个连接排队 5 轮

每个连接上是**串行的**,请求排队等响应。

域名分片的思路

用多个子域名指向同一台服务器:

graph TD
    A[www.example.com] --> D[源站服务器]
    B[img1.example.com] --> D
    C[img2.example.com] --> D
    E[img3.example.com] --> D

    F[每个域名 6 个连接] --> G[3 × 6 = 18 个并行连接]
3 个子域名 × 6 个连接 = 18 个并行连接
18 个连接同时下载,30 个资源几轮就完了

分片前后对比

不分片(1 个域名,6 个连接):

连接1: ████ req1  ████ req7  ████ req13 ████ req19 ████ req25
连接2: ████ req2  ████ req8  ████ req14 ████ req20 ████ req26
连接3: ████ req3  ████ req9  ████ req15 ████ req21 ████ req27
连接4: ████ req4  ████ req10 ████ req16 ████ req22 ████ req28
连接5: ████ req5  ████ req11 ████ req17 ████ req23 ████ req29
连接6: ████ req6  ████ req12 ████ req18 ████ req24 ████ req30
                                                           ↑ 很长

分片后(3 个域名,18 个连接):

img1 连接1-6: ████ 1 ████ 7 ████ 13 ████ 19 ████ 25
img2 连接1-6: ████ 2 ████ 8 ████ 14 ████ 20 ████ 26
img3 连接1-6: ████ 3 ████ 9 ████ 15 ████ 21 ████ 27
                                                   ↑ 快多了

实现方式

前端 HTML 里只需把资源 URL 的域名换掉:

<!-- 以前 -->
<img src="https://www.example.com/images/logo.png">

<!-- 分片后 -->
<img src="https://img1.example.com/images/logo.png">

服务器端不用改动,所有子域名 DNS 解析到同一台机器就行。

域名分片的代价

代价 说明
DNS 解析开销 每个子域名都要单独解析,5-50ms
TLS 握手开销 每个新域名要单独做 TLS 握手
缓存碎片化 不同域名的缓存独立,不能共享,可能重复下载

为什么现在不需要了

HTTP/1.1 + 域名分片 HTTP/2
并行方式 多个 TCP 连接 一个 TCP 连接内多路复用
开 30 个连接 需要 5 个子域名骗浏览器 不需要,一根连接全搞定
额外开销 每个子域名 DNS + TLS 只有一次
缓存 每个子域名独立缓存 统一缓存

演进路线

graph TD
    A[HTTP/1.0 无 Keep-Alive<br/>每个请求一个连接] --> B[HTTP/1.1 + Keep-Alive<br/>一个连接串行复用]
    B --> C[域名分片<br/>多域名骗浏览器多开连接]
    C --> D[HTTP/2 多路复用<br/>一个连接真正并行]
    D --> E[HTTP/3 QUIC<br/>连 TCP 队头阻塞都干掉]

常见陷阱

不要在 HTTP/2 上使用域名分片

HTTP/2 的多路复用让域名分片变成了负优化——多了 DNS 和 TLS 开销,还破坏了缓存统一性。如果你的站点已经上了 HTTP/2,应该去掉域名分片。

分片数量不是越多越好

3-4 个子域名通常就够了。过多子域名意味着更多 DNS 查询和 TLS 握手,反而拖慢加载速度。


练习题

如果一个网站同时有 HTTP/1.1 和 HTTP/2 的用户,域名分片还有意义吗?
答案

需要权衡。HTTP/1.1 用户能从分片中获益(更多并行连接),但 HTTP/2 用户会受额外 DNS/TLS 开销之苦。建议直接升级到 HTTP/2 全站覆盖,而不是为少数 HTTP/1.1 用户保留分片。

浏览器对同一域名 6 个连接的限制是怎么来的?
答案

这是浏览器厂商的**经验值**,不是协议规定。2000 年代初期,6 个连接被认为是在"并行效率"和"服务器负载"之间的平衡点。这个限制在 HTTP/2 时代已经过时,但浏览器仍然保持兼容。