在瀏覽器中輸入URL并按回車之后會發生什么
1. 輸入URL并解析
輸入URL后,瀏覽器會解析出協議、主機、端口、路徑等信息,并構造一個HTTP請求(瀏覽器會根據請求頭判斷是否又HTTP緩存,并根據是否有緩存決定從服務器獲取資源還是使用緩存資源)
2. DNS域名解析,將域名解析成對應的IP地址
DNS是一種用于將域名(www.baidu.com)轉換成IP地址(220.181.111.188)的分布式系統。
3. 建立TCP三次握手
4. 瀏覽器發送HTTP/HTTPS請求到web服務器
5. 服務器處理HTTP請求并返回HTTP報文
服務器會接受請求并將其傳遞給請求處理程序并發送HTTP響應,一般響應報文包含:請求網頁以及狀態碼,壓縮類型,如何緩存的頁面,設置cookie;
6. 瀏覽器渲染頁面
7. TCP四次揮手斷開連接
HTTP版本演變
HTTP/1.0
是HTTP協議的第一個正式版本,主要有以下特性:
- 引入了請求頭和響應頭,支持多種請求方法和狀態碼
- 不支持持久連接,每次請求都需要建立新的連接
HTTP/1.1
- ?長連接
為了解決HTTP/1.0每次請求都需要建立新的連接的問題,HTTP/1.1提出了長連接(持久連接),只要客戶端和服務器任意一端沒有明確提出斷開連接,則保持TCP連接狀態
? ? ? ? 2. 管道網絡傳輸
在同一個TCP連接里面,客戶端可以發起多個請求,只要第一個請求發出去了,不必等其回來,就可以發送第二個請求,可以減少整體的響應時間。
客戶端需要請求兩個資源。以前的做法是,在同一個TCP連接里面,先發送A請求,然后等服務器做出回應,收到后再發出B請求。那么,管道機制則是允許瀏覽器同時發出A請求和B請求。
但是服務器必須按照接受請求的順序發送對這些管道化請求的響應。
如果服務端在處理A請求時耗時比較長,那么后續的請求的處理都會被阻塞,這稱為隊頭阻塞
HTTP/1.1管道解決了請求的對頭阻塞,但沒有解決響應的對頭阻塞。
????????3.對頭阻塞
當順序發送的請求序列中的一個請求因為某種原因被阻塞時,在后面排隊的所有請求也一同被阻塞了,會招致客戶端一值請求不到數據,。
但是HTTP/1.1仍然存在很多問題:
- 頭部冗余:每個請求你和響應都需要帶有一定的頭部信息,每次互相發送相同的頭部造成的浪費較多;
- 服務器是按請求的順序相應的,如果服務器響應慢,會導致客戶端一直請求不到數據,也就是隊頭阻塞;
- 沒有請求優先級控制
- 請求只能從客戶端開始,服務器只能被動響應
HTTP/2
HTTP/2? ?協議是基于HTTPS的,所以HTTP/2的安全性也是有保障的
- 頭部壓縮:HTTP/2使用了HPACK壓縮算法對請求頭和響應頭部進行壓縮,減少了傳輸的頭部數據量,降低了延遲
- 二進制幀:HTTP/2將數據分割成二進制幀進行傳輸,分為頭信息幀和數據信息幀,增加了數據傳輸的效率
- 并發傳輸:引出Stream概念,多個Stream復用在一條TCP連接,針對不同的HTTP請求用獨一無二的Stream ID來區分,接收端可以通過Stream ID 有序組裝成HTTP消息,不同Stream的幀可以亂序重發送的,因此可以并發不同的Stream,也就是HTTP/2可以并行交錯地發送請求和響應
- 服務器推送:在HTTP/2中,服務器可以對客戶端的一個請求發送多個響應,即服務器可以額外的向客戶端推送資源,而無需客戶端明確的請求
但是HTTP/2仍然存在隊頭阻塞的問題,只不過在傳輸層
HTTP/2是基于TCP協議來傳輸數據的,TCP是字節流協議,TCP層必須保證收到的字節數據是完整且連續的,這樣內核才會將緩沖區里的數據返回給HTTP應用,那么【當前1個字節數據】沒有到達時,后收到的字節數據只能存放在內核緩沖區中,只有等到者1個字節的數據到達時,HTTP/2應用層才能從內核中拿數據,這就是HTTP/2的隊頭阻塞問題。
并發實現:
先來理解三個概念:Stream、Messager、frame
從圖中可以看出
- 一個TCP連接包含一個或多個Stream,Stream時HTTP/2并發的關鍵技術
- Stream包含1個或多個Message,Message對應HTTP/1中的請求或響應,由HTTP頭部和包體構成
- Message里面包含一條或多條frame,frame時HTTP/2最小單位,以二進制壓縮格式存放HTTP/1中的內容
HTTP 消息可以由多個 Frame 構成
一個 Frame 可以由多個 TCP 報文構成
在 HTTP2 連接上,不同 Stream 的幀可以亂序發送(因此可以并發不同的 Stream),接收端可以通過 Stream ID 有序組裝 HTTP 消息。
HTTP/2 通過 Stream 實現的并發,比 HTTP/1.1 通過 TCP 連接實現并發要牛逼的多,因為當 HTTP/2 實現 100 個并發 Stream 時,只需要建立一次 TCP 連接,而 HTTP/1.1 需要建立 100 個 TCP 連接,每個 TCP 連接都要經過 TCP 握手、慢啟動以及 TLS 握手過程,這些都是很耗時的。
HTTP/2 還可以對每個 Stream 設置不同優先級,幀頭中的「標志位」可以設置優先級,比如客戶端訪問 HTML/CSS 和圖片資源時,希望服務器先傳遞 HTML/CSS,再傳圖片,那么就可以通過設置 Stream 的優先級來實現,以此提高用戶體驗。
HTTP/3
HTTP/3 基于 QUIC 協議,具有以下特點:
- 零 RTT 連接建立:QUIC 允許在首次連接時進行零往返時間(Zero Round Trip Time)連接建立,從而減少了連接延遲,加快了頁面加載速度。
- 無隊頭阻塞:QUIC 使用 UDP 協議來傳輸數據。一個連接上的多個 stream 之間沒有依賴,如果一個 stream 丟了一個 UDP 包,不會影響后面的 stream,不存在 TCP 隊頭阻塞
- 連接遷移:QUIC 允許在網絡切換(如從 Wi - Fi 到移動網絡)時,將連接遷移到新的 IP 地址,從而減少連接的中斷時間。
- 向前糾錯機制:每個數據包除了它本身的內容之外,還包括了部分其他數據包的數據,因此少量的丟包可以通過其他包的冗余數據直接組裝而無需重傳。向前糾錯犧牲了每個數據包可以發送數據的上限,但是減少了因為丟包導致的數據重傳。
HTTP 緩存
將資源(如網頁、圖像、腳本等)的副本存儲在客戶端或中間代理服務器上,以便將來的請求可以直接從緩存中獲取,而不必重新從服務器下載資源。這有助于減少網絡延遲,提高頁面加載速度,并減輕服務器的負擔。
緩存可以解決什么問題
- 減少不必要的網絡傳輸,節約帶寬
- 更快的加載頁面
- 減少服務器負載,避免服務過載的情況出現
強制緩存
強緩存:瀏覽器判斷請求的目標資源是否有效命中強緩存,如果命中,則可以直接從內存中讀取目標資源,無需與服務器做任何通訊。
Expires 強緩存:設置一個強緩存時間,此時間范圍內,從內存中讀取緩存并返回。
Cache-Control 強緩存:http1.1 中增加該字段,使用 max-age 指令,可以設置資源在緩存中的最長有效時間,單位為秒。例如,Cache-Control: max-age=3600 表示資源在緩存中保留 3600 秒
協商緩存
與強制緩存不同,協商緩存依賴于客戶端和服務器之間的交互,在協商緩存中,服務器在響應中提供了資源的一些標識信息,客戶端在后續請求中通過這些信息來判斷資源是否發生了變化,進而判斷是否需要重新傳輸資源。
下面是常用于協商緩存的一些頭部字段
ETag 和 If-None-Match:
- ETag 是服務器為資源生成的唯一標識符,可以是根據文件內容計算出的哈希值。
- 客戶端在請求頭部的 If-None-Match 字段中攜帶上次響應的 ETag 值。
- 服務器比較請求中的 If-None-Match 值與當前資源的 ETag 值,如果匹配,表示資源未發生變化,返回狀態碼 304 Not Modified。
Last-Modified 和 If-Modified-Since:
Last-Modified 是資源的最后修改時間,服務器在響應頭部中返回。
客戶端在請求頭部的 If-Modified-Since 字段中攜帶上次響應的 Last-Modified 時間。
服務器比較請求中的 If-Modified-Since 值與當前資源的 Last-Modified 值,如果請求時間早于資源的最后修改時間,表示資源未發生變化,返回狀態碼 304 Not Modified。