HTTP/1.1 定于 1999 年,之后十几年只有补丁没有新版。 卡住它的不是想不出办法,而是改协议要动全世界。
上一节说网页越来越重,这一节说协议为什么跟不上。 这里算的三种走法,是第九章 SPDY 与 HTTP/2 的直接动机。
一、为什么改不动
HTTP/1.1 是文本协议:人能读懂,代理能改写,中间设备能塞私货。 这是它流行的原因,也是它改不动的原因——中间有太多设备在解析它,动一个字都可能让某台老设备失效。 所以十几年里的进展都是「加法」:加首部、加方法、加状态码,从不敢动请求行的形状。 真正的换代必须等中间设备换代。
二、瓶颈一:每个资源一个往返
HTTP/1.0 默认「一个资源一条连接」,用完就关。六个资源就是六次握手,六次挥手。 Demo 里按跨城 40 毫秒算:每资源一条新连接要 510 毫秒, 换成持久连接(复用一条 TCP)降到 310 毫秒,省掉 39%。 省下的全部是握手——这就是 2.7 节「持久连接」的价值。
三、瓶颈二:队头阻塞(HOL)
管线化(pipelining)能把六个请求一口气塞进去,理论上只要 110 毫秒,比持久连接再省 65%。 它 1999 年就写进标准了,却几乎没人用。 原因是响应必须按请求顺序回。 第一个资源如果是个慢接口,后面五个就算早就算好了也只能等着——这就是队头阻塞。 瓶颈在协议,不在带宽,加带宽没用。 HTTP/2 的解法是给每个请求编号、允许乱序交错回(多路复用)。 但它在 TCP 上跑,一旦丢包,整条连接的所有流一起等——所以 HTTP/3 干脆换到 QUIC(跑在 UDP 上)。
四、动手 Demo:六个资源,三种走法的时间账
不测网络,只算模型:给定往返 40 毫秒、每资源传输 5 毫秒,三种走法各要多久。 数字由代码算,不是估的。
rtt, xfer, n = 40.0, 5.0, 6
# ① 每资源一条新连接:握手 + 请求 + 传输
serial = n * (rtt + rtt + xfer)
# ② 一条持久连接:握手一次,之后每个资源一个往返
keepalive = rtt + n * (rtt + xfer)
# ③ 持久连接加管线化:一次把请求全塞进去
pipelined = rtt + rtt + n * xfer
实跑输出:
--------------------------------------------------------------------
HTTP/1.1 卡在哪儿:六个资源的两种走法
--------------------------------------------------------------------
假定单程往返 40 毫秒
资源个数 6 个
每资源传输 5 毫秒
① 每资源一条新连接 510 毫秒
② 持久连接(串行) 310 毫秒
③ 持久连接加管线化 110 毫秒
②比①省 200 毫秒(39%)
③比②再省 200 毫秒(65%)
管线化看着最划算,但响应必须按请求顺序回,队头那个一卡,后面全堵——这就是 HTTP/1.1 停在原地的原因。
510 / 310 / 110 三个数,对应「每资源一连接 / 持久连接 / 管线化」。
注意 ③ 只有理论值——现实中因为队头阻塞拿不到。
③比②再省 200 毫秒(65%) 这个比例高得可疑,是因为模型里每个资源的传输时间只有 5 毫秒、
往返却有 40 毫秒,往返被放大成了绝对主角。资源越碎,这个比例越夸张。
30 秒实验
- 把
n从 6 改成 60,重跑,看三种走法的差距是被拉大还是缩小。 - 把
rtt改成 5(同机房),再跑,看管线化的优势还剩多少。 - 把
xfer改成 200(大文件),看「省往返」这件事还值不值钱。
常见误区
- 「上了 HTTP/2 就没有队头阻塞」——TCP 层的队头阻塞还在,一个包丢了整条连接一起等。 要根治得换 QUIC。
- 「管线化能解决问题」——标准里有,浏览器全线关掉了。
- 「HTTP/1.1 太老所以慢」——它慢在「一个连接一次只能有一个在途请求」,不是老。 同机房小文件场景它依然够快。
自测三问(点开对答案)
1. 持久连接省下的是哪一段时间? —— TCP 三次握手(以及慢启动)。请求本身的一个往返省不掉。 2. 管线化为什么没人用? —— 响应必须按请求顺序返回,一个慢响应会堵住后面全部,而且中间代理对管线化支持很差。 3. HTTP/2 解决了什么、没解决什么? —— 解决了 HTTP 层的队头阻塞(多路复用);没解决 TCP 层的——丢一个包全连接等。协议卡住的原因说清了。接下来回到最底层:这些协议是怎么分层的。
- ☐ (本节完,下一节 1.3.1 TCP/IP协议族)
相关笔记
- 12 课 · 计算机网络(TCP 的可靠传输与拥塞控制)
- 36 课 · 图解TCP/IP(第5版)(传输层怎么保证不丢)
- 📘 图解HTTP · 索引