推薦閱讀:https://www.cnblogs.com/zwtblog/tag/計算機網路/
計算機網路-相關文章可以移步:https://www.cnblogs.com/zwtblog/tag/計算機網路/
HTTP 基本概念
HyperText Transfer Protocol -- 超文字傳輸協議
狀態碼分類:
完整詳情見:https://www.cnblogs.com/zwtblog/p/16077173.html
分類 | 分類描述 |
---|---|
1** | 資訊,伺服器收到請求,需要請求者繼續執行操作 |
2** | 成功,操作被成功接收並處理 |
3** | 重定向,需要進一步的操作以完成請求 |
4** | 客戶端錯誤,請求包含語法錯誤或無法完成請求 |
5** | 伺服器錯誤,伺服器在處理請求的過程中發生了錯誤 |
各個版本示意圖:
HTTP/1.1 相⽐ HTTP/1.0 提⾼了什麼效能?
HTTP/1.1 相⽐ HTTP/1.0 效能上的改進:
- 使⽤ TCP ⻓連線(keepalive)的⽅式改善了 HTTP/1.0 短連線造成的效能開銷。
- ⽀持管道(pipeline)⽹絡傳輸,只要第⼀個請求發出去了,不必等其回來,就可以發第⼆個請求出去,可以
減少整體的響應時間。
但 HTTP/1.1 還是有效能瓶頸:
- 請求 / 響應頭部(Header)未經壓縮就傳送,⾸部資訊越多延遲越⼤。只能壓縮 Body 的部分;
傳送冗⻓的⾸部。每次互相傳送相同的⾸部造成的浪費較多; - 伺服器是按請求的順序響應的,如果伺服器響應慢,會招致客戶端⼀直請求不到資料,也就是隊頭阻塞;
- 沒有請求優先順序控制;
- 請求只能從客戶端開始,伺服器只能被動響應。
HTTP/1.1如何優化?
- 避免發請求 -- 快取
- 減少請求次數
- 減少重定向
- 合併請求
- 延遲傳送
- 減少響應資料
- 有損/無失真壓縮
避免發請求
快取
伺服器在傳送 HTTP 響應時,有過期的時間,並把這個資訊放到響應頭部中,這樣客戶端在檢視響應頭部的資訊時,⼀旦發現快取的響應是過期的,則就會重新傳送⽹絡請求。
如果資料並未變更,也可以對比摘要。
減少請求次數
減少重定向
合理使用代理伺服器
合併請求
例如合併圖片
延遲傳送請求
例如 在部落格園訪問我的部落格的時候,頁面時一次性載入出來的,是否可以優化成⽤戶向下滑動⻚⾯的時候,再向伺服器獲取接下來的資源,這樣就達到了延遲傳送請求的效果。
HTTP/1.1 的效能瓶頸,HTTP/2 做了什麼優化?
最⼤效能問題就是 HTTP/1.1 的⾼延遲,主要原因如下⼏個:
- 併發連線有限,瀏覽器最⼤併發有限, 握⼿耗時,以及TCP 慢啟動過程給流量帶來的影響。
- 隊頭阻塞,同⼀連線只能在完成⼀個 HTTP 事務(請求和響應)後,才能處理下⼀個事務。
- HTTP 頭部巨⼤且重複,由於 HTTP 協議是⽆狀態的,每⼀個請求都得攜帶 HTTP 頭部。
- 不⽀持伺服器推送訊息,因此當客戶端需要獲取通知時,只能通過定時器不斷地拉取訊息。
HTTP/2 只在應⽤層做了改變,還是基於 TCP 協議傳輸,應⽤層⽅⾯為了保持功能上的相容,HTTP/2 把 HTTP 分
解成了「語義」和「語法」兩個部分,「語義」層不做改動,與 HTTP/1.1 完全⼀致,⽐如請求⽅法、狀態碼、頭
欄位等規則保留不變。
但是,HTTP/2 在「語法」層⾯做了很多改造,基本改變了 HTTP 報⽂的傳輸格式。
HTTP/2的優化
- 頭部壓縮
- 二進位制幀
- 併發傳輸
- 主動推送資源
頭部壓縮
HTTP/1.1 報⽂中 Header 部分存在的問題:含很多固定的欄位,⽐如Cookie、User Agent、Accept 等,⼤量的請求和響應的報⽂⾥有很多欄位值都是重複的。欄位是 ASCII 編碼的。
HTTP/2 對 Header 部分做了⼤改造,把以上的問題都解決了。
HTTP/2 沒使⽤常⻅的 gzip 壓縮⽅式來壓縮頭部,⽽是開發了 HPACK 演算法,HPACK 演算法主要包含:
- 靜態字典;(高頻頭部或者欄位,共61種)
- 動態字典;(自行構建。Index 62 起步)
- Huffman 編碼 編碼(壓縮演算法);
客戶端和伺服器兩端都會建⽴和維護「字典」,⽤⻓度較⼩的索引號表示重複的字串,再⽤ Huffman 編碼壓縮資料,可達到 50%~90% 的⾼壓縮率。
Web 伺服器都會提供類似 http2_max_requests 的配置,⽤於限制⼀個連線上能夠傳輸的請求數量,
避免動態表⽆限增⼤,請求數量到達上限後,就會關閉 HTTP/2 連線來釋放記憶體。
二進位制幀
HTTP/2 將 HTTP/1 的⽂本格式改成⼆進位制格式傳輸資料,使⽤位運算能⾼效解析。
HTTP/2 把響應報⽂劃分成了兩個幀(Frame), HEADERS(⾸部)和 DATA(訊息負載) 是幀的型別。
併發傳輸
通過 Stream 這個設計,多個 Stream 復⽤⼀條 TCP 連線,達到併發的效果,解決了HTTP/1.1 隊頭阻塞的問題,提⾼了 HTTP 傳輸的吞吐量。
HTTP 訊息可以由多個 Frame 構成,以及 1 個 Frame 可以由多個 TCP 報⽂構成。
在 HTTP/2 連線上,不同 Stream 的幀是可以亂序傳送的(因此可以併發不同的 Stream ),因為每個幀的頭部會攜帶 Stream ID 資訊,所以接收端可以通過 Stream ID 有序組裝成 HTTP 訊息,⽽同一 Stream 內部的幀必須是嚴格有序的。
HTTP/2 還可以對每個 Stream 設定不同優先順序,幀頭中的「標誌位」可以設定優先順序
主動推送資源
客戶端發起的請求,必須使⽤的是奇數號 Stream,伺服器主動的推送,使⽤的是偶數號 Stream。
伺服器在推送資源時,會通過 PUSH_PROMISE 幀傳輸 HTTP 頭部,並通過幀中的 Promised Stream ID 欄位告知客戶端,接下來會在哪個偶數號 Stream 中傳送包體。
HTTP/3
HTTP/2 協議是基於 TCP 實現的,於是存在的缺陷有三個。
- 隊頭阻塞;(TCP保證完整 有序導致的)
- TCP 與 TLS 的握⼿時延遲;
- ⽹絡遷移需要重新連線;
由下圖可知:此次升級使用 谷歌制定的一種基於UDP的低時延的網際網路傳輸層協議, QUIC(Quick UDP Internet Connection) 。再就是幀格式在HTTP/2的基礎上做了一些改變。
為什麼HTTP/3要基於UDP?可靠嗎?
詳情見:https://www.cnblogs.com/zwtblog/p/16081957.html
肝不動了,見諒。下次更新,更新了加連結。
參考
- https://juejin.cn/post/6984315270038814727#heading-5
- https://medium.com/faun/http-2-spdy-and-http-3-quic-bae7d9a3d484
- https://developers.google.com/web/fundamentals/performance/http2?hl=zh-cn
- https://blog.cloudflare.com/http3-the-past-present-and-future/
- https://tools.ietf.org/html/draft-ietf-quic-http-34
- https://tools.ietf.org/html/draft-ietf-quic-transport-34#section-17