HTTP发展历程
从 HTTP/0.9 到 HTTP/3 的演进过程
问题
介绍 HTTP 协议的发展历程,各版本有什么特点和改进?
解答
HTTP/0.9(1991年)
最早的 HTTP 版本,极其简单:
- 只支持 GET 方法
- 没有请求头和响应头
- 只能传输 HTML 文本
- 响应完成后立即关闭连接
GET /index.html
HTTP/1.0(1996年)
引入了基本的协议框架:
- 增加 POST、HEAD 方法
- 引入请求头和响应头
- 支持状态码(200、404、500 等)
- 支持多种内容类型(Content-Type)
- 每次请求都需要新建 TCP 连接
GET /index.html HTTP/1.0
Host: example.com
User-Agent: Mozilla/5.0
HTTP/1.1(1997年)
目前仍广泛使用的版本:
- 持久连接:默认
Connection: keep-alive,复用 TCP 连接 - 管道化:可以连续发送多个请求(但响应必须按序返回)
- Host 头必需:支持虚拟主机
- 新增方法:PUT、DELETE、OPTIONS、TRACE
- 缓存控制:Cache-Control、ETag
- 分块传输:Transfer-Encoding: chunked
GET /api/data HTTP/1.1
Host: example.com
Connection: keep-alive
Cache-Control: max-age=3600
问题:队头阻塞(Head-of-Line Blocking)—— 前一个请求未完成,后续请求被阻塞。
HTTP/2(2015年)
基于 Google 的 SPDY 协议:
- 二进制分帧:将数据拆分为更小的帧传输
- 多路复用:同一连接上并行处理多个请求,解决应用层队头阻塞
- 头部压缩:HPACK 算法压缩请求头
- 服务器推送:主动推送资源给客户端
- 请求优先级:可设置资源加载优先级
# 一个 TCP 连接上同时传输多个流
Stream 1: GET /style.css
Stream 2: GET /script.js
Stream 3: GET /image.png
问题:TCP 层的队头阻塞仍然存在 —— 丢包会阻塞所有流。
HTTP/3(2022年)
基于 QUIC 协议(UDP):
- 基于 UDP:使用 QUIC 协议替代 TCP
- 彻底解决队头阻塞:流之间相互独立,丢包只影响单个流
- 更快的连接建立:0-RTT 或 1-RTT 握手
- 连接迁移:网络切换时保持连接(基于 Connection ID)
- 内置 TLS 1.3:默认加密
# 连接建立对比
HTTP/1.1 + TLS: TCP 握手(1 RTT) + TLS 握手(2 RTT) = 3 RTT
HTTP/3 + QUIC: QUIC 握手(1 RTT,含 TLS) = 1 RTT
版本对比
| 特性 | HTTP/1.0 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|---|
| 连接复用 | ❌ | ✅ | ✅ | ✅ |
| 多路复用 | ❌ | ❌ | ✅ | ✅ |
| 头部压缩 | ❌ | ❌ | ✅ | ✅ |
| 服务器推送 | ❌ | ❌ | ✅ | ✅ |
| 传输协议 | TCP | TCP | TCP | UDP(QUIC) |
| 队头阻塞 | 有 | 有 | TCP层有 | 无 |
关键点
- HTTP/1.1 引入持久连接,但存在队头阻塞问题
- HTTP/2 通过多路复用解决应用层队头阻塞,但 TCP 层问题仍在
- HTTP/3 基于 QUIC/UDP,彻底解决队头阻塞,支持 0-RTT 快速连接
- 每个版本都是为了解决上一版本的性能瓶颈
- 目前 HTTP/1.1 和 HTTP/2 是主流,HTTP/3 正在逐步普及
目录