HTTP 连接与版本演进
复习
- HTTP 请求与响应:请求-响应模型
- 套接字:请求由 TCP 连接承载
- TCP 为什么需要连接:建立连接本身有开销
TL;DR
- 早期每个请求都新建一次连接,开销很大
- 持久连接让多个请求复用同一条连接
- 多路复用进一步让多个请求并行、互不阻塞
- 版本演进的主线,就是不断减少等待与开销
正文
HTTP 的每个请求,都要通过一条传输层连接来传递。那么,一个网页要取几十个资源(图片、样式、脚本),难道要建几十次连接?
这正是 HTTP 版本演进要解决的核心问题。
每请求一连接的时代
最早的 HTTP/1.0,基本是“一次请求,一条连接”:请求完就关,下个请求再重新建立。
问题很明显:建立连接本身有成本(三次握手、慢启动),如果每个小资源都来一遍,大量时间都花在“准备连接”上,而不是真正传数据。这就像每买一样东西都重新排一次队,效率极低。
持久连接
HTTP/1.1 引入了持久连接(keep-alive):一条连接建立后,可以反复用来发多个请求,用完先不关。
这省掉了大量重复的握手开销。
但它带来一个新问题:在一条连接上,请求通常还得一个接一个地处理。前一个没处理完,后面的就得排队等——哪怕它们互不相关。这叫“队头阻塞”。只要队首那个请求慢,后面全被拖住。
多路复用
为了打破排队,HTTP/2 引入了多路复用:把请求拆成一个个小帧,打上标记,在同一条连接上交错发送。接收方按标记重新拼装,于是多个请求可以并行进行,互不阻塞。
再往后,HTTP/3 干脆换了底层传输方式(基于 UDP 的 QUIC),进一步减少连接建立和丢包恢复的等待。
把这条演进线串起来看,主线非常清晰:一切都是为了减少等待、降低开销。 手段在变,目标没变。
思考题 1
每次请求都新建 TCP 连接,代价主要体现在哪里?
思考题 2
HTTP/2 的多路复用,解决了 HTTP/1.1 的什么问题?
小结
知识点
- HTTP/1.0 每请求新建连接,开销大
- HTTP/1.1 用持久连接复用连接
- 一条连接上仍可能存在队头阻塞
- HTTP/2 多路复用让请求并行进行
参考资料
- Wikipedia(zh):HTTP/2:支持多路复用的 HTTP 版本
- Wikipedia(zh):HTTP持久连接:在同一连接上发送多个请求
思考题答案(仅供参考)
思考题 1
代价在建立连接本身:需要三次握手,还可能经历慢启动等阶段,在真正传数据之前就要花掉若干往返时间。资源多时,这些开销会被反复叠加,明显拖慢加载。
思考题 2
解决了 HTTP/1.1 的队头阻塞:在一条连接上,前面的请求没完成会拖住后面的。多路复用把请求拆成小帧交错发送,使多个请求在同一条连接上并行处理,互不阻塞。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪