http/2 基础教程
目录
1. 知识点
1.1. 队头阻塞
- 在 http1.1 中,一个TCP连接一般情况下,只能同时处理一个请求/响应。下一个请求/响应,需要等上一个处理完才能进行 (即使采用 pipelining , 同时发送多个请求,客户端还是会按发送顺序,先处理第一个响应)。 因此, 如果前面请求处理时间过长, 那么就会阻塞后面的请求。
- 目前浏览器,通过对同一域名,开启多个连接(chrome 是6个)来降低该问题的影响。
1.2. h2 基本知识
- h2 分为 分帧层 和 数据层
- h2 是基于帧的 二进制协议
1.3. h1 与 h2 请求头部的差异
h1
GET / HTTPS/1.1 Host: www.bing.com HTTP/1.1 200 OK content-type: text/html
h2
:authority: www.bing.com :method: GET :path: / :scheme: https :status: 200 content-type: text/plain
h1 的 请求/状态行 换成了 :method: GET
这样的 伪首部
1.4. h1 与 h2 解析消息的差异
- h1 是通过 文本分隔符 来解析协议,需要不断读取字节直到遇到分隔符,这将导致下列问题:
- 一次只能处理一个请求/响应
- 无法预先判断需要使用多少内存
- h2 通过 帧 来解析协议, 每一帧的长度是已知的, 且可用 stream id 标记帧, 故可以多路复用
1.5. h1 与 h2 其他差异
- h1 消息首部和消息体, 对应成h2的 HEADERS帧 和 DATA帧
- 因为 h2 使用帧,帧长度是已知的,所以不需要 分块编码
- h1 使用 101 来升级协议(例如websocket), h2使用 ALPN
2. TODO http/2 详解
2.1. 连接
2.2. 帧
2.3. 流
2.4. 首部压缩
2.5. 服务端推送
3. FAQ
3.1. http/1.1 有哪些问题?
- 队头阻塞
- 臃肿的header
- 低效的 tcp 连接 (每个tcp连接, 都要经历 拥塞窗口调节 )
3.2. http2 解决了http/1.1 的哪些问题
3.2.1. 队头阻塞问题
因为 h2 是分帧的,请求和响应可以交错甚至多路复用,所以可以并行发送和接收多个请求/响应, 从而解决队头阻塞问题。
3.2.2. 首部压缩
h2 采用 hpack 压缩 header
3.2.3. 低效的tcp 连接
- 因为多路复用的存在,针对一个域名,可以只开启一个连接,从而只有一次 拥塞窗口调节 阶段
- 但是因为底层仍然是 tcp, 这会导致一个连接出现异常,会影响到所有http请求
4. 工具
4.1. nghttp2
# -v 打印debug # -n 丢弃下载内容 # -a 下载html指明的,在同一域名的资源 # -s 打印统计信息 # -H <header> 添加请求首部 -H ":method PUT" nghttp -vn -H "x-custom: hello" https://www.bing.com
4.2. chromium
禁用 http2
chromium --disable-http2