最近部門組織了一次前端性能優化交流會,你們從輸入頁面 URL 到最終頁面展現內容這個過程提出了許多優化點。但同時發現不少同窗對 HTTP 協議層的知識不能串聯起來,因而整理了這篇文章,但願能夠給你們帶來一絲靈感。javascript
當咱們在頁面上發起一個 AJAX 請求的時候,在網絡協議層面都經歷了哪些內容?前端
// 發起請求 fetch('https://baidu.com') // 協議層1... // 協議層2... // 協議層3... .then(res=> // 獲得結果 console.log(res) })
如上述代碼所示,咱們對 baidu.com
發起了一個網絡請求,最終在 then 方法中獲得了具體的響應內容。java
使用 Wireshark 抓包結果以下:算法
圖中能夠看到,請求 baidu.com 時,首先經過 TCP 3 次握手創建鏈接,而後經過 HTTP 傳輸內容,最後經過 TCP 4 次揮手斷開鏈接。瀏覽器
真實的過程更加複雜,咱們主要分析如下幾點:緩存
創建鏈接階段安全
創建 TCP 鏈接(傳輸層)性能優化
發送數據階段服務器
要獲取 baidu.com 的網頁內容,就須要和 baidu 服務器創建鏈接,怎樣創建這個鏈接呢?網絡
經過 DNS 解析,咱們就能找到 baidu 服務器對應的 IP 地址。
如圖:
通過 DNS 解析後,咱們就能獲得 baidu.com 的 IP 地址了:39.156.69.79 和 220.181.38.148,一般客戶端會隨機選中一個 IP 地址進行通訊。
其實 IP 不必定要經過 DNS 解析才能獲取,它一般會被客戶端緩存,只有在 DNS 緩存都沒有命中的時候纔會請求 DNS 服務器。
判斷步驟以下:
有了 IP 地址以後,客戶端和服務器端就能創建鏈接了,首先是創建 TCP 鏈接。
TCP 是一種面向鏈接的、可靠的、基於字節流的傳輸層通訊協議。
在這一層,咱們傳輸的數據會按照一個個的字節裝入報文中,當報文的長度達到最大分段(MSS)時,就會發送這個報文。若是傳輸的報文很長,可能會被拆分紅多個 TCP 報文進行傳輸。
TCP 報文頭以下:
咱們主要看如下幾點:
TCP 標記:
接下來,咱們看一下 TCP 是怎樣創建鏈接的?
如圖所示,創建 TCP 鏈接須要 3 個步驟,俗稱三次握手。
第二次握手:服務器端回發一個 ack=x+1 的標識,表示確認收到第一次握手,同時發送本身的標識 seq=y。
第三次握手:客戶端發送 ack=y+1 的標識,標識確認收到第二次握手。
通過了 3 次握手,即保證了客戶端和服務器端都能正常發送和接收數據,TCP 鏈接也就創建成功了。
上文中說到,TCP 是可靠的傳輸,這是爲何呢?
這是由於 TCP 內部使用了 中止等待協議 ARQ ,它經過 確認 和 重傳 機制,實現了信息的可靠傳輸。
例如:
在這期間,若是某一條數據好久都沒有獲得確認,客戶端就會重傳這條數據。這樣一來,對於與每一次發送的數據,服務器端都獲得了確認,即保證了數據的可靠性。
雖然 ARQ 能夠知足數據可靠性,但每次只能發送和確認一個請求,效率過低了,因而就產生了連續 ARQ 協議。
連續 ARQ 協議 會連續發送一組數據,而後再批量等待這一組數據的確認信息,比如把單線程 ARQ 變成了多線程,大大提升了資源的利用效率。
如:
在這個流程中,服務器端不須要對每個數據都返回確認信息,而是接收到多個數據時一併確認,這個方式叫作 累計確認。
這裏有個疑問,TCP 的每一次握手,是怎麼找到目的服務器呢?
答:經過 IP 協議。
IP 協議的目的是實現網絡層的數據轉發,它經過路由器不斷跳轉,最終把數據成功送達目的地。
上文中的每一次 TCP 握手以及數據交互,都是經過 IP 協議去傳輸的。
IP 報文頭以下:
咱們關注如下兩點就能夠了:
發起一個 IP 請求執行流程以下:
路由表存在於計算機或路由器中,由目的 IP 地址、子網掩碼、下一跳地址、發送接口四部分組成。經過目的 IP 地址,便可找到下一跳的地址,進行轉發。
例如:A 要向 G 發送 IP 數據。
具體流程以下:
A 生成 IP 頭部(源 IP:A ,目的 IP:G)
B 生成 IP 頭部(源 IP:A ,目的 IP:G)
E 生成 IP 頭部(源 IP:A ,目的 IP:G)
你是否有疑惑,爲何 IP 會按照這條路徑向 G 傳輸數據呢?
其實,上圖中的路徑並不是只有一條,咱們經過 ABEG 到達了目的地 G,一樣也能夠經過 ABCFHG 到達 G,這兩種路徑都能完成任務,爲何 IP 不選擇 ABCFHG 這條路徑呢?
這就涉及到了 IP 尋址的算法。
咱們能夠把網絡中的全部計算機都看作是一個點,計算機之間的鏈接看作是一條線,這些點和線就組合成了一個圖。
例如:
經過上圖,咱們就把複雜的網絡轉化成了數學問題。IP 尋址算法,其實就是圖論中的最短路徑的算法。
最短路徑算法在 IP 協議中有 2 種實現:
RIP 協議
原理
OSPF 協議
原理
經過以上兩個協議,咱們就能找到通往目的地的路徑了。
這裏拋出一個問題:IP 數據是怎樣從一個路由器跳到另外一個路由器呢?
答:經過以太網協議。
IP 協議主要是用來尋找最優路徑的,具體的傳輸是由以太網協議來作的。
以太網屬於數據鏈路層,它主要負責相鄰設備的通訊。原理是經過查詢交換機 Mac 表,找到通訊雙方的物理接口,進而開始通訊。
以太網報文頭以下:
咱們只用關心如下 3 個點:
能夠看到,以太網層都是經過 Mac 地址進行通訊的,這裏的 Mac 地址是哪裏來的呢?
答:經過 ARP 協議。
ARP 協議 是一個經過解析 IP 地址來找尋 Mac 地址的協議。IP 地址轉換成 Mac 地址後,就能進行以太網數據傳輸了。
例如:
當機器 A 向機器 C 發送數據時:
B 查詢 Mac 表,根據目的地 Mac 地址,匹配 C 的硬件接口。
通過上述的流程,咱們就找到了目的機器的硬件接口。
經過以太網協議,咱們找到了目標機器的硬件接口,接下來要怎麼發送信息呢?
答:經過物理層。
在沒有 WiFi 的年代,咱們只能經過插網線來進行上網,網線其實就是物理層的設備之一。
網線能夠由多種材料組成,最多見的就是光纖和電纜。
光纖和電纜的傳輸原理相似,都是經過兩個信號來模擬二進制數據的,一個信號即爲一個比特。
如:在光纖中,咱們經過觀察光的閃動,便可得知傳輸的二進制數據。
有了這些物理設備,咱們就能把複雜的數據轉換成光信號或者電信號進行傳輸了。
發送數據能夠分爲兩個步驟:
本文的案例是發送一個 HTTPS 的請求,因此在發送數據以前,會建立一個 SSL 安全層,用於數據加密。
一般的加密方法有兩種:
非對稱加密
對稱加密
互聯網通訊是雙向的,因此咱們須要使用對稱加密,但是,怎樣才能保證通訊雙方都有一把相同的鑰匙呢?
目前的解決方案:
祕鑰協商過程如圖:
圖中劃重點:
Ok,祕鑰協商以後,咱們的 SSL 安全層也就建好了。
祕鑰協商時存在一個問題:
祕鑰協商時,怎麼保證是和真正的服務器在協商,而不是一箇中間人呢?答:數字證書。
數字證書重點關注 2 個部分:
其中,數字簽名又是由服務器公鑰和證書私鑰加密生成的,目的是爲了防止服務器公鑰被篡改。
有了數字證書,客戶端就能經過驗證證書,來判斷服務器是不是真正的服務器了。
驗證邏輯以下:
能夠看到,數字證書經過一樣的算法進行解密,若是獲得相同的信息摘要,就能保證數據是有效的,若是不一致,則會驗證失敗,拒絕後續的請求。
到這裏爲止,全部的準備工做都就緒了,接下來纔是發送 HTTP 請求。
HTTP 協議其實就是制定了一個通訊規則,規定了客戶端和服務器之間的通訊格式。
以請求 baidu 首頁爲例:
如上圖所示,發起 HTTP 請求時,必須遵照如下規則:
GET
/
1.1
Host
、User-Agent
、Accept
服務器響應請求時,一樣遵照了 HTTP 響應規則:
1.1
200
OK
Date
、Server
、ETag
、Last-Modified
等只要咱們遵照這個規則,就能進行 HTTP 通訊了。
到目前爲止,咱們已經分析完成了數據請求的全部過程,你是否都理解了呢?
本文經過一個網絡請求,對整個 HTTP、TCP、IP、以太網等協議進行了流程化分析,最後再梳理一下:
最後,若是你對此有任何想法,歡迎留言評論!