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

日期: 2023-02-08

Validate