Web性能优化-什么是多路复用

1. HTTP/2 的帧与流等概念

HTTP/2 是基于二进制帧(Frame),他将一个TCP连接分为若干个流(Stream),每个流中可以传输若干消息(Message),每个消息由若干最小的二进制帧(Frame)组成。

科普:什么是二进制?如果一个二进制人类看得懂,那他就是字符串,否则就是二进制

-------------------
| Length | Type   |
-------------------
| Flag | StreamID |
-------------------
|   Payload       |
-------------------

前面九个字节代表 Length (长度)、Type (类型)、Flags (标记位)、StreamID (所在流的 ID),第五部分 Payload (数据),一般为16 K - 16 M(这里说的数据不只是请求体,包含了从 HTTP 请求头开始的所有)

与 HTTP/1.* 的区别

GET

  1. 这里假设是一个 Frame,前面这个框代表前九个字节
  2. header 代表这是请求头
  3. + (true) 号代表当前这部分结束
  4. 冒号开头的表示伪头,h2 现在用这三行表示为以前的请求头第一部分
  5. 以前的冒号变成了等于号(因为冒号被占用了)
  6. 大写变成了小写,不允许小写

POST

  1. 至少三个 Frame
  2. 第一个 Frame,- END_STREAM 表示请求没有结束,- END_HEADERS 表示请求头也没有结束
  3. 第二个 Frame,COUTINUATION 表示这是一个继续,要和前面一个一起看,+ END_HEADERS 到我这一帧,请求头结束了
  4. 以前请求的第三部分(回车),到 h2 就不需要了,删除了
  5. DATA 数据,+ END_STREAM 代表请求到这里都结束了

响应

总结

基本没什么区别,只不过是吧以前一个请求、一个响应变成了不同的帧,让那九个字节关联起所有的帧,还有伪头的概念

2. HTTP/2的流与多路复用

  1. 上次说到 HTTP/1.1 管道的概念,之所以不能使用就是因为响应的时候必须要按顺序
  2. 但是在 HTTP/2 中就没有这个问题了,他每个响应都会告诉你对应的是哪个,因为他有前面 9 个字节可以做标记,所以在管道中每个请求响应都是独立的,大大的提升了效率
  3. 但是 H2 并不仅仅是加了标记,由于顺序是乱的,所以请求方需要去做一个整合,响应方 Frame 太多了请求方一般还一般需要压缩在发送
  4. 有了多路复用以后,以前的并行方案就没有必要了,并行的话还要多开好几个连接
  5. 一个管道中能开多少个“路”呢?答案是 100 可以, 1000 个也可以,一般来说 100 都算少的,所以他的效率是极高的

3. HTTP/2 的 Server Push 的利与弊

先说结论,我们实际生活中并不会或者说很少使用到这个功能

  1. 首先客户端还是需要先发送第一个请求
  2. 但是此时服务器会主动多返回一些东西回来
  3. 当客户端再需要请求这些文件的时候,就会发现已经有了,就不再请求了

那么问题来了,服务器怎么知道客户端需要哪些东西呢?

答案是程序员认为去提前写好的

配置 Server Push

方法一:Nginx

// Nginx
location {
  root   /usr/share/nginx*html
  index  index.html index.htm
  http2_push  /style.css
  http2_push  /example.css
}

方法二:Nginx 和 响应头

// Nginx
location = / {
  ...
  http2_push_preload on
}
// index.html 响应头
Link: </style.css>; rel=preload; as=style
  1. 一般这样的配置非常繁琐,如果文件名称变动,还需要后台配合来改配置,一般没人会这么做
  2. 还有现在的前端都是工程化了,文件名一般都是混合了哈希,后端根本不知道文件名
  3. 所以几乎没有人用
  4. 当然 Server Push 很好,可以提前响应,但是现实状况是后台不知道提前去响应什么
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章