跳转到内容

Padmanabhan-Mogul 1995 — 用秒表证明:持久连接 + 流水线能砍掉 HTTP 延迟

待复核

Padmanabhan-Mogul 1995 是一篇对照实验报告。它改 Mosaic 客户端和 NCSA httpd,在真实链路上用秒表掐时间,比较三种加载方式谁更快:

  1. 旧 HTTP(一请求一 TCP 连接)
  2. 持久连接(keep-alive / long-lived):一根 TCP 复用多次请求
  3. 持久连接 + pipelining(流水线):请求连发,不必等上一个响应回来

日常类比:你点 11 杯奶茶。

  • 旧 HTTP = 每点一杯都重新排队、付款、领单。
  • 持久连接 = 排一次队,11 杯一杯杯点完再走。
  • pipelining = 排一次队,11 杯一口气全报给店员,店员按顺序做。

同期还有人提 T/TCP(把握手和首包合并),但本文秒表里没有跑它;姊妹篇 Mogul 1995 从部署角度讨论过。本文贡献是:在跨美广域链路上把前三种跑出可比较的数字。

不读这篇,就解释不通:

  • 为什么 HTTP/1.1(1997, RFC 2068)默认持久连接,pipelining 却只是可选——本文测出流水线最快,后来浏览器因队头阻塞不敢默认开
  • 为什么浏览器对 HTTP/1.1 站点常开约 6 条并行连接——用多连接绕开单连接流水线的队头阻塞
  • 为什么 HTTP/2(2015)用一条连接上的多路复用——把「少握手 + 并发请求」做对
  • 为什么 HTTP/3 / QUIC 的 0-RTT、TCP Fast Open(RFC 7413)能成立——它们接的是「砍握手 RTT」那条线,不是本文实测的主方案

这是 Web 性能里较早用实现 + 对照测量给 HTTP 改法拍板的论文之一。

  • 作者:Padmanabhan(UC Berkeley)、Mogul(DEC WRL)
  • 实现:改 Mosaic V2.4 客户端 + NCSA httpd V1.3,跑在 DECstation / ULTRIX 上
  • 链路:局域网 Ethernet(RTT 近 0)对照跨美 T1(最佳 RTT 约 70ms
  • 被测:一个 HTML + 多张内联图(图数、图大小可变)
方案TCP 握手次数每对象额外等待
旧 HTTP 一请求一连接N(对象数)1 RTT(再加握手)
持久连接11 RTT(等响应再发下一请求)
持久 + pipelining1≈0(请求可连发)
  1. 远程小图场景:持久 + pipelining 相对旧协议,延迟常砍一半以上(文中 remote、约中位图大小)
  2. 收益大头来自 pipelining;单开持久连接也有帮助,但不如合用
  3. 图越大、传输越占主导,相对收益变小——优化的是 RTT 税,不是带宽

案例 1:算一下为什么 pipelining 这么猛

Section titled “案例 1:算一下为什么 pipelining 这么猛”

设 RTT = 100ms,10 张图,每张 50ms 传输。

旧 HTTP:每对象 (1 RTT 握手 + 1 RTT 请求-响应 + 50ms) = 250ms × 10 = 2500ms

持久连接:1 RTT 握手 + 10 × (1 RTT + 50ms) = 100 + 1500 = 1600ms

持久 + pipelining:1 RTT 握手 + 1 RTT 首请求 + 10 × 50ms ≈ 700ms

省下来的不是带宽——是等空气来回的时间(RTT 税)。

案例 2:用 curl 看「连接有没有被复用」

Section titled “案例 2:用 curl 看「连接有没有被复用」”
Terminal window
# -v 看握手;两次请求若复用,第二次不应再完整三次握手
curl -v -o /dev/null https://example.com/ 2>&1 | grep -E 'Connected|HTTP/'
curl -v -o /dev/null https://example.com/ 2>&1 | grep -E 'Connected|HTTP/'

逐部分解释:HTTP/1.1 默认倾向复用;若每次都看到新的 Connected to ...,说明连接没留下来。今天叠了 TLS,每条新连接更贵,持久连接比 1995 年更值。

打开 Chrome DevTools → Network:

  • HTTP/1.1:常每域名约 6 条 TCP 并行(绕开 pipelining 队头阻塞)
  • HTTP/2:1 条 TCP,流级多路复用(流水线思想的成熟版)
  • HTTP/3:QUIC/UDP,可 0-RTT(砍握手,另一条进化线)
  1. pipelining 队头阻塞:第一个响应慢,后面全堵——本文静态资源测得顺,真实动态接口常拖累,浏览器长期不敢默认开
  2. 广域收益更大:约 70ms RTT 时砍半很明显;局域网 RTT 近 0 时,单开持久连接原文大约只省 5–15%,流水线仍有帮助,但别把广域结论原样套进机房内网
  3. T/TCP 不是银弹:它能省握手,却不解决多对象 slow-start/连接风暴;且早期设计有源地址伪造风险,后被弃用,精神由 TCP Fast Open 等继承
  4. 没测 HTTPS:1995 年还在 SSL 早期;今天新连接常再叠 1–2 个 TLS RTT,复用连接更重要

今天还有用的洞察

  • 任何 RTT 敏感设计——把「往返次数」当一等公民(对照文中约 70ms 广域量级)
  • 「很多小对象」场景——页面资源、HTTP API、RPC,优先连接复用
  • 改协议前先做对照实验 + 真实链路,别只靠纸面 RTT 计数

不适用

  • 大文件单次下载(瓶颈是带宽,RTT 优化感弱;原文大图相对收益明显变小)
  • 机房内近零 RTT 调用(省不出多少握手时间)
  • 实时双向通道(WebSocket / WebTransport 不是「请求-响应拉一堆小对象」模型)
  • 1990:HTTP/0.9「一请求一连接」——简单到能快速实现
  • 1994:Web 爆发,多对象页面触发 TCP 握手风暴
  • 1994-10:本文早期版在 WWW 1994(Chicago)发表
  • 1995-12:完整版见 Computer Networks and ISDN Systems
  • 1997-01:RFC 2068 HTTP/1.1 把持久连接默认化,pipelining 可选
  • 2015 / 2022:HTTP/2 多路复用、HTTP/3/QUIC 0-RTT 分别接上「并发」与「砍握手」两条线
  1. 协议优化的关键单位常是 RTT,不是字节
  2. 对照实验 > 纯理论:把旧协议、长连接、流水线放同一条链路跑,数字比口号硬
  3. 修错地方收益有限:只砍握手、不解决多小对象往返,对 Web 页面帮助有限
  4. 性能最好 ≠ 能普及:pipelining 测得最快,却因队头阻塞与部署难长期未默认;更简单的持久连接先成事实标准