推薦閱讀: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