1 DNS 解析流程
1.1?什么是DNS域名解析
????????在生活中我們會經常遇到域名,比如說CSDN的域名www.csdn.net,百度的域名www.baidu.com,我們也會碰到IP,現在目前有的是IPV4,IPV6。那這兩個有什么區別呢?IP地址是互聯網上計算機唯一的邏輯地址,通過IP地址實現不同計算機之間的相互通信,每臺聯網的計算機都需要通過IP地址來互相聯系和分別。
? ? ? ? 但是由于IP地址是由一串容易混淆且很難記憶的數字串構成,這對我我們日常生活訪問不同網站是很困難的。基于此,人們在IP地址的基礎上又發展出了一種更容易識別的符號化標識,這種標識由人們自行選擇的字母和數字構成,相比IP地址來說更加容易被識別和記憶,逐漸替代IP地址成為互聯網用戶進行訪問互聯的主要入口。這種符號化的標識就是域名。
? ? ? ? 域名雖然說更加容易被用戶所接受和使用,但是計算機只能識別純數字構成的IP地址,不能直接讀取域名。因此想要達到訪問效果,就需要將域名翻譯成IP地址。而DNS域名解析承擔的就是這種翻譯效果。
1.2 DNS域名解析流程
????????例如,當我們在瀏覽器地址中輸入www.csdn.net時,DNS會有7個步驟,其中前兩個步驟是在本地電腦中完成的,后面8個步驟涉及到真正的域名解析服務器:
1.2.1 第一步? 檢查瀏覽器緩存
????????本地電腦會檢查瀏覽器緩存中有沒有這個域名對應的解析過的IP地址,如果緩存中有,這個解析過程就結束。瀏覽器緩存域名也是有限制的,不僅瀏覽器緩存大小有限制,而且緩存的時間也有限制,通常情況為幾分鐘到幾個小時不等,域名被緩存的時間限制可以通過TTL屬性來設置。這個緩存時間太長和太短都不大好,如果時間太長,一旦域名被解析到的Ip有變化(例如百度作為一個大型的互聯網服務提供商,它的IP地址就是動態變化的),會導致被客戶端緩存的域名無法解析到變化后的IP地址,這段時間內有一部分用戶無法訪問網站。如果時間太短,會導致用戶每一次訪問網站都需要重新解析一次域名。
1.2.2?第二步? 查找操作系統緩存? ? ? ? ?
? ? ? ? 如果瀏覽器緩存中沒有數據,瀏覽器會查找操作系統緩存中是否有這個域名對應的DNS解析結果。操作系統也有一個域名解析的過程,在Linux中可以通過/etc/hosts文件來設置,而在Windows中可以通過配置?C:\Windows\System32\drivers\etc\hosts文件來設置,用戶可以將任何域名解析到能夠訪問的IP地址。例如,我們在測試時可以將一個域名解析到一臺測試的服務器上,這樣不用修改任何代碼就能測試到單獨服務器上的代碼的業務邏輯是否正確。正是因為有這種本地DNS解析的規程,所以有黑客就可能通過修改用戶的域名來把特定的域名解析到他指定的IP地址上,導致這些域名被劫持。
PS:也有一種情況,電腦會先查找Host文件,再查找瀏覽器緩存。但是現在有的瀏覽器會先查找緩存,本文按第二種情況贅述。?
1.2.3 第三步 本地DNS服務器
? ? ? ? 前兩個過程無法解析的時候,就需要用到我們網絡配置中的“DNS服務器地址”了。操作系統會把這個域名發送給這個本地DNS服務器。每個完整的內網通常都會配置本地DNS服務器,例如用戶是在學校或者工作單位接入互聯網,那么用戶的本地DNS服務器肯定在學校或者工作單位里面。他們一般都會通過緩存域名解析結果,當然緩存時間是會受到域名的失效時間控制的。大約80%的域名解析到這里就結束了,后續的DNS迭代和遞歸也是由本地DNS服務器配置。
windows配置方式:
控制面板->網絡和共享中心->更改適配器設置->選中目標適配器右鍵選擇屬性->IPV4或者IPV6,然后配置DNS地址。
?1.2.4 第四步 根域名服務器
? ? ? ? 如果本地DNS服務器沒有命中,則本地域名服務器向上級域名服務器進行迭代查詢,并首先向根域名服務器發起請求
1.2.5 第五步 頂級域名服務器
? ? ? ? 由根DNS服務器返回給本地DNS域名服務器一個頂級DNS服務器地址。
1.2.6 第六步 Name Server域名服務器
? ? ? ? 接受請求的頂級DNS服務器查找并返回此域名對應的Name Server域名服務器的地址,這個Name Server服務器就是我們需要訪問的網站域名提供商的服務器,其實該域名的解析任務就是由域名提供商的服務器來完成。比如我要訪問www.XXXX.com,而這個域名是X公司注冊獲得的,那么X公司的服務器上就會有www.XXXX.com的相關信息。
? ? ? ? Name Server服務器會查詢存儲的域名和IP的映射關系表,再把查詢出來的域名和IP地址等等信息,連同一個TTL值返回給本地DNS服務器。
1.2.7 第七步 IP和TTL值
? ? ? ? 返回該域名對TTL值,本地DNS服務器會緩存這個域名和IP的對應關系,緩存時間由TTL值控制。把解析的結果返回給本地電腦,本地電腦根據TTL值緩存在本地緩存中,域名解析過程結束在實際的DNS解析過程中。
可能還不止這七個步驟,例如Name Server可能有很多級,或者有一個GTM來負載均衡控制,這都有可能會影響域名解析過程。
?
2 瀏覽器輸入域名訪問整個流程
2.1 第一步 DNS域名解析
具體見上文。
2.2 第二步 建立TCP連接
在經過DNS解析之后,瀏覽器已經獲取了對應網站的IP地址,通過“三次握手”連接到網站服務器。
2.2.1?什么是三次握手?
建立一個 TCP 連接需要“三次握手”,缺一不可:
- 一次握手:客戶端發送帶有 SYN(SEQ=x) 標志的數據包 -> 服務端,然后客戶端進入 SYN_SEND 狀態,等待服務端的確認;
- 二次握手:服務端發送帶有 SYN+ACK(SEQ=y,ACK=x+1) 標志的數據包 –> 客戶端,然后服務端進入 SYN_RECV 狀態;
- 三次握手:客戶端發送帶有 ACK(ACK=y+1) 標志的數據包 –> 服務端,然后客戶端和服務端都進入ESTABLISHED 狀態,完成 TCP 三次握手。
當建立了 3 次握手之后,客戶端和服務端就可以傳輸數據了。
2.2.2??為什么要進行3次握手?
三次握手的目的是建立可靠的通信信道,說到通訊,簡單來說就是數據的發送與接收,而三次握手最主要的目的就是雙方確認自己與對方的發送與接收是正常的。
- 第一次握手:Client 什么都不能確認;Server 確認了對方發送正常,自己接收正常
- 第二次握手:Client 確認了:自己發送、接收正常,對方發送、接收正常;Server 確認了:對方發送正常,自己接收正常
- 第三次握手:Client 確認了:自己發送、接收正常,對方發送、接收正常;Server 確認了:自己發送、接收正常,對方發送、接收正常
三次握手就能確認雙方收發功能都正常,缺一不可。
更詳細的解答可以看這個:TCP 為什么是三次握手,而不是兩次或四次? - 車小胖的回答 - 知乎 。
2.3 第三步 發送HTTP請求
????????TCP三次握手之后,客戶端和服務器端成功建立了連接,之后瀏覽器會向服務器特定端口發送HTTP請求。
以Chrome 瀏覽器為例,按下 F12 即可進入開發者模式,Network 一欄查看HTTP請求的具體報文。
????????一個 HTTP 報文由請求行(Request Line)、請求頭部(Request Headers)、空行(Blank Line)以及請求體(Request Body)構成,請求行中規定了請求方法、URI 以及 HTTP 的版本,關于每個字段的詳細解釋,之前的小節已經進行了闡述。
2.4 第四步 服務器端解析請求
????????當一個 HTTP 請求打進服務器之后,一般的流程是:網關層(例如Ngnix)最先獲取請求,然后路由轉發到具體的Web服務,經過一段業務邏輯之后,可能還會查詢數據庫,最后將處理的結果返回給瀏覽器客戶端。
????????對于后端開發程序員來說,日常的工作就集中在服務器端,特別是流程圖中的"Web業務服務"這塊,例如基于 Spring 框架、Django 框架或者ThinkPHP 框架進行業務邏輯開發和上線。
2.5 第五步 返回HTTP響應
????????服務器端處理業務結果之后,也要返回 HTTP 響應,HTTP 響應由狀態行(Status Line)、響應頭部(Response Headers)、空行(Blank Line)以及響應體(Response Body)構成,關于每個部分的細節也不再贅述。需要特別注意的是,響應體中的各種錯誤碼定義:
2.6 第六步 TCP四次揮手
????????當瀏覽器獲取了域名對應的頁面信息,為了避免服務器和客戶端雙方的資源損耗,客戶端會請求斷開 TCP 連接,和三次握手的過程相似。
????????斷開一個 TCP 連接則需要“四次揮手”,缺一不可,TCP 四次揮手的過程可以總結為::
- 第一次揮手:客戶端發送一個 FIN(SEQ=x) 標志的數據包->服務端,用來關閉客戶端到服務端的數據傳送。然后客戶端進入 FIN-WAIT-1 狀態。
- 第二次揮手:服務端收到這個 FIN(SEQ=X) 標志的數據包,它發送一個 ACK (ACK=x+1)標志的數據包->客戶端 。然后服務端進入 CLOSE-WAIT 狀態,客戶端進入 FIN-WAIT-2 狀態。
- 第三次揮手:服務端發送一個 FIN (SEQ=y)標志的數據包->客戶端,請求關閉連接,然后服務端進入 LAST-ACK 狀態。
- 第四次揮手:客戶端發送 ACK (ACK=y+1)標志的數據包->服務端,然后客戶端進入TIME-WAIT狀態,服務端在收到 ACK (ACK=y+1)標志的數據包后進入 CLOSE 狀態。此時如果客戶端等待 2MSL 后依然沒有收到回復,就證明服務端已正常關閉,隨后客戶端也可以關閉連接了。
只要四次揮手沒有結束,客戶端和服務端就可以繼續傳輸數據
?
?2.6.1 為什么需要四次揮手??
TCP 是全雙工通信,可以雙向傳輸數據。任何一方都可以在數據傳送結束后發出連接釋放的通知,待對方確認后進入半關閉狀態。當另一方也沒有數據再發送的時候,則發出連接釋放通知,對方確認后就完全關閉了 TCP 連接。
舉個例子:A 和 B 打電話,通話即將結束后。
- 第一次揮手:A 說“我沒啥要說的了”
- 第二次揮手:B 回答“我知道了”,但是 B 可能還會有要說的話,A 不能要求 B 跟著自己的節奏結束通話
- 第三次揮手:于是 B 可能又巴拉巴拉說了一通,最后 B 說“我說完了”
- 第四次揮手:A 回答“知道了”,這樣通話才算結束。
2.6.2 四次揮手需要等待2MSL的意義?
第四次揮手時,客戶端發送給服務端的 ACK 有可能丟失,如果服務端因為某些原因而沒有收到 ACK 的話,服務端就會重發 FIN,如果客戶端在 2*MSL 的時間內收到了 FIN,就會重新發送 ACK 并再次等待 2MSL,防止 Server 沒有收到 ACK 而不斷重發 FIN。
MSL(Maximum Segment Lifetime) : 一個片段在網絡中最大的存活時間,2MSL 就是一個發送和一個回復所需的最大時間。如果直到 2MSL,Client 都沒有再次收到 FIN,那么 Client 推斷 ACK 已經被成功接收,則結束 TCP 連接。
2.7 瀏覽器解析HTML? ? ?
服務器返回給客戶端的是 HTML 以及 CSS、Javascript 代碼,要展示為靜態頁面,還需要經過瀏覽器的解析行為。
瀏覽器內核引擎解析 HTML 文檔并且將標簽轉換為 DOM(Document Object Model,文檔對象模型)樹的 DOM 節點,不同瀏覽器的渲染解析流程大同小異。
同時,瀏覽器內核引擎還會解析 CSS 生成 CSS 規則樹,按照從右到左的順序讀取選擇器。
另外,在瀏覽器中還有個"JS腳本解析器",解析 HTML 和 CSS 是多線程同時執行的,CSS 解析失敗不會影響 HTML 內容的解析,但是如果 JS 腳本解析過程中觸發了異常,會直接終止 HTML 內容的解析。關于更詳細的解析動作,作為后端開發,我們不需要了解太多,這塊也不會作為面試考察的內容。
?
更詳細的可以拜讀此篇文章https://zhuanlan.zhihu.com/p/166440446
?