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 很好,可以提前響應,但是現實狀況是後臺不知道提前去響應什麼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章