HTTP請求過程
-
DNS 域名解析 -->
-
發起 TCP 的 3 次握手 -->
1) Client首先發送一個連接試探,ACK=0 表示確認號無效,SYN = 1 表示這是一個連接請求或連接接受報文,同時表示這個數據報不能攜帶數據,seq = x 表示Client自己的初始序號(seq = 0 就代表這是第0號包),這時候Client進入syn_sent狀態,表示客戶端等待服務器的回復
2) Server監聽到連接請求報文后,如同意建立連接,則向Client發送確認。TCP報文首部中的SYN 和 ACK都置1 ,ack = x + 1表示期望收到對方下一個報文段的第一個數據字節序號是x+1,同時表明x為止的所有數據都已正確收到(ack=1其實是ack=0+1,也就是期望客戶端的第1個包),seq = y 表示Server 自己的初始序號(seq=0就代表這是服務器這邊發出的第0號包)。這時服務器進入syn_rcvd,表示服務器已經收到Client的連接請求,等待client的確認。
3) Client收到確認后還需再次發送確認,同時攜帶要發送給Server的數據。ACK 置1 表示確認號ack= y + 1 有效(代表期望收到服務器的第1個包),Client自己的序號seq= x + 1(表示這就是我的第1個包,相對于第0個包來說的),一旦收到Client的確認之后,這個TCP連接就進入Established狀態,就可以發起http請求了。
-
TCP 為什么需要3次握手?
舉個例子:
假設一個老外在故宮里面迷路了,看到了小明,于是就有下面的對話:
老外: Excuse me,Can you Speak English?
小明: yes 。
老外: OK,I want ...
在問路之前,老外先問小明是否會說英語,小明回答是的,這時老外才開始問路2個計算機通信是靠協議(目前流行的TCP/IP協議)來實現,如果2個計算機使用的協議不一樣,那是不能進行通信的,所以這個3次握手就相當于試探一下對方是否遵循TCP/IP協議,協商完成后就可以進行通信了,當然這樣理解不是那么準確。
為什么HTTP協議要基于TCP來實現?
目前在Internet中所有的傳輸都是通過TCP/IP進行的,HTTP協議作為TCP/IP模型中應用層的協議也不例外,TCP是一個端到端的可靠的面向連接的協議,所以HTTP基于傳輸層TCP協議不用擔心數據的傳輸的各種問題。
-
建立 TCP 連接后發起 http 請求 -->
-
服務器響應 http 請求, 瀏覽器得到html代碼
-
瀏覽器解析html代碼,并請求html代碼中的資源
????????瀏覽器拿到index.html文件后,就開始解析其中的html代碼,遇到js/css/image等靜態資源時,就向服務器端去請求下載(會使用多線程下載,每個瀏覽器的線程數不一樣),這個時候就用上keep-alive特性了,建立一次HTTP連接,可以請求多個資源,下載資源的順序就是按照代碼里的順序,但是由于每個資源大小不一樣,而瀏覽器又多線程請求請求資源
????????瀏覽器在請求靜態資源時(在未過期的情況下),向服務器端發起一個http請求(詢問自從上一次修改時間到 現在有沒有對資源進行修改),如果服務器端返回304狀態碼(告訴瀏覽器服務器端沒有修改),那么瀏覽器會直接讀取本地的該資源的緩存文件。 -
瀏覽器對頁面進行渲染呈現給用戶
- 渲染引擎 (Webkit Blink Gecko Trident Presto)
- JavaScript引擎(V8)
DNS解析
-
Step1: 首先拿到 URL 后,瀏覽器會尋找本地的 DNS 緩存,看看是否有對應的 IP 地址
- 如果緩存中存在那就好了, 直接向該IP地址發送
- 如果沒有,那就得向 DNS Server 發送一個請求,找到你想要的 IP 地址。
Step2: 首先他會向你的 ISP(互聯網服務提供商) 相關的 DNS servers 發送 DNS query。然后這些 DNS 進行遞歸查詢(recursive)。所謂的遞歸查詢,就是能夠直接返回對應的IP地址,而不是其他的 DNS server 地址。
Step3: 如果上述的 DNS Servers 沒有你要的域名地址,則就會發送迭代查詢,即會先從 root nameservers 找起。 即是假如你要查詢 www.example.com ,會先從包含根結點的 13 臺最高級域名服務器開始。
Step4: 接著,以從右向左的方式遞進,找到 com. 然后向包含 com 的 TLD(頂級域名) nameservers 發送 DNS 請求。接著找到包含 example 的 DNS server。
Step5: 現在進入到了example.com 部分,即是現在正在詢問的是權威服務器,該服務器里面包含了你想要的域名信息,也就是拿到了最后的結果 record 。
Step6: 遞歸查詢的 DNS Server 接受到這 record 之后, 會將該record 保存一份到本地。 如果下一次你再請求這個 domain 時,我就可以直接返回給你了。由于每條記錄都會存在 TLL ,所以 server 每隔一段時間都會發送一次請求,獲取新的 record,
Step7: 最后,再經由最近的 DNS Server 將該條 record 返回。 同樣,你的設備也會存一份該 record 的副本。 之后,就是 TCP 的事了,下面是一張萌萌的簡化圖:
迭代查詢的流程
流程: . => com. => .exampl.com. => www.example.com. => IP adress
DNS PC和Mobile 域名發散和收斂
在 PC 上,我們采用域名發散策略,是因為在 PC 端上,DNS 解析通常而言只需要幾十 ms ,可以接受。
-
而移動端,2G 網絡,3G網絡,4G網絡/wifi 強網,而且移動 4G 容易在信號不理想的地段降級成 2G ,通過大量的數據采集和真實網絡抓包分析(存在DNS解析的請求),DNS的消耗相當可觀,2G網絡大量5-10s,3G網絡平均也要3-5s(數據來源于淘寶)。 下面附上在 2G,3G,4G, WIFI 情況下 DNS 遞歸解析的時間 (ms):
QQ截圖20160408104038 因為在增加域的同時,往往會給瀏覽器帶來 DNS 解析的開銷。所以在這種情況下,提出了域名收斂,減少域名數量可以降低 DNS 解析的成本。
在 2 個域名分散條件下,網頁的加載速度提升較大,而第 3 個以后就比較慢了。 所以,一般來說,域名分散的數量最好在 3 以下。