DNS 協(xié)議是什么?完整查詢過程?為什么選擇使用 UDP 協(xié)議發(fā)起 DNS 查詢?
點擊上方 三分鐘學前端,關(guān)注公眾號
回復(fù)交流,加入前端編程面試算法每日一題群
引言
你可能了解 DNS 協(xié)議是什么?那你了解 DNS 完整查詢過程是什么嗎?它底層是基于 TCP 還是 UDP 喃?TCP 與 UDP 又各自負責 DNS 的哪些部分喃?
本文就從以下幾個方面循序漸進走進 DNS 協(xié)議、它的完整查詢過程以及底層是基于 UDP 還是 TCP 實現(xiàn)?
DNS 協(xié)議是什么? 域名結(jié)構(gòu) 域名解析緩存優(yōu)化 DNS 查詢方式有哪些 DNS 完整查詢過程 為什么選擇基于 UDP 協(xié)議發(fā)起 DNS 查詢,而不是 TCP?
DNS 協(xié)議是什么?

DNS(Domain Name System:域名系統(tǒng)),與 HTTP、FTP 和 SMTP 一樣,DNS 協(xié)議也是應(yīng)用層的協(xié)議,用于將用戶提供的主機名(域名)解析為 IP 地址。
簡單來說,DNS 就像是一個自動的電話號碼簿,我們可以直接撥打 47.105.127.0 呼叫對方,但這不方便記錄、記憶,DNS 提供一種手段能夠讓我們直接撥打?qū)Ψ降挠蛎?www.pzijun.cn 找到對方

??就是將域名 www.baidu.com 解析成 ip地址:1.1.1.1 ,思考一下??
DNS 如何根據(jù)域名解析成 IP 地址?
域名結(jié)構(gòu)
DNS 的核心系統(tǒng)是一個三層的樹狀、分布式服務(wù),基本對應(yīng)域名的結(jié)構(gòu):
根域名服務(wù)器(Root DNS Server):管理頂級域名服務(wù)器,返回“com”“net”“cn”等頂級域名服務(wù)器的 IP 地址 頂級域名服務(wù)器(Top-level DNS Server):管理各自域名下的權(quán)威域名服務(wù)器,比如 com 頂級域名服務(wù)器可以返回 apple.com 域名服務(wù)器的 IP 地址 權(quán)威域名服務(wù)器(Authoritative DNS Server):管理自己域名下主機的 IP 地址,比如 apple.com 權(quán)威域名服務(wù)器可以返回 www.pzijun.cn 的 IP 地址

有了??這個系統(tǒng)后,任何域名都可以在上面這個結(jié)構(gòu)中進行從上到下查詢,例如,你要訪問“www.pzijun.cn”,就要進行下面的三次查詢:
訪問根域名服務(wù)器,它會告訴你“cn”頂級域名服務(wù)器的地址; 訪問“cn”頂級域名服務(wù)器,它再告訴你“pzijun.com”域名服務(wù)器的地址; 最后訪問“pzijun.com”域名服務(wù)器,就得到了“www.pzijun.cn”的地址
但如果全世界的域名解析都往這個系統(tǒng)里擠,這個系統(tǒng)可能被擠癱瘓了,即使不癱瘓,解析速度也會大打折扣,所以 DNS 采取了一種非常有效的手段來解決這個問題: 緩存
域名緩存優(yōu)化
域名緩存有以下兩種方式:
非權(quán)威域名服務(wù)器(本地域名服務(wù)器)緩存 :各大運營服務(wù)商或大公司都有自己的 DNS 服務(wù)器,一般部署在距離用戶較近地方,代替用戶用戶訪問核心 DNS 系統(tǒng),可以緩存之前的查詢結(jié)果,如果已經(jīng)有了記錄,就無需再向根服務(wù)器發(fā)起查詢,直接返回對應(yīng)的 IP 地址 本地計算機 DNS 記錄緩存 : 瀏覽器緩存 :瀏覽器在獲取某一網(wǎng)站域名的實際 IP 地址后,進行緩存,之后遇到同一域名查詢之前的緩存結(jié)果即可,有效減少網(wǎng)絡(luò)請求的損耗。每種瀏覽器都有一個固定的 DNS 緩存時間,如 Chrome 的過期時間是 1 分鐘,在這個期限內(nèi)不會重新請求 DNS 操作系統(tǒng)緩存 :操作系統(tǒng)里有一個特殊的“主機映射”文件,通常是一個可編輯的文本,在 Linux 里是 /etc/hosts,在 Windows 里是C:\WINDOWS\system32\drivers\etc\hosts,如果操作系統(tǒng)在緩存里找不到 DNS 記錄,就會找這個文件

DNS 查詢方式
DNS 查詢有兩種方式:遞歸 和 迭代 。
一般來說,DNS 客戶端設(shè)置使用的 DNS 服務(wù)器一般都是 遞歸服務(wù)器 ,它負責全權(quán)處理客戶端的 DNS 查詢請求,直到返回最終結(jié)果
而 DNS 根域名服務(wù)器之間一般采用 迭代查詢 方式,以免根域名服務(wù)器的壓力過大
遞歸查詢

迭代查詢

DNS 完整查詢過程
將我們上面所說的域名服務(wù)器之間的 DNS 查詢請求過程和域名緩存結(jié)合起來,完整查詢過程??:
首先搜索 瀏覽器的 DNS 緩存 ,緩存中維護一張域名與 IP 地址的對應(yīng)表 如果沒有命中??,則繼續(xù)搜索 操作系統(tǒng)的 DNS 緩存 如果依然沒有命中???♀?,則操作系統(tǒng)將域名發(fā)送至 本地域名服務(wù)器 ,本地域名服務(wù)器查詢自己的 DNS 緩存,查找成功則返回結(jié)果(注意:主機和本地域名服務(wù)器之間的查詢方式是 遞歸查詢 ) 若本地域名服務(wù)器的 DNS 緩存沒有命中???,則本地域名服務(wù)器向上級域名服務(wù)器進行查詢,通過以下方式進行 迭代查詢 (注意:本地域名服務(wù)器和其他域名服務(wù)器之間的查詢方式是迭代查詢,防止根域名服務(wù)器壓力過大):
首先本地域名服務(wù)器向根域名服務(wù)器發(fā)起請求,根域名服務(wù)器是最高層次的,它并不會直接指明這個域名對應(yīng)的 IP 地址,而是返回頂級域名服務(wù)器的地址,也就是說給本地域名服務(wù)器指明一條道路,讓他去這里尋找答案 本地域名服務(wù)器拿到這個頂級域名服務(wù)器的地址后,就向其發(fā)起請求,獲取權(quán)限域名服務(wù)器的地址 本地域名服務(wù)器根據(jù)權(quán)限域名服務(wù)器的地址向其發(fā)起請求,最終得到該域名對應(yīng)的 IP 地址
本地域名服務(wù)器 將得到的 IP 地址返回給操作系統(tǒng),同時自己將 IP 地址 緩存 起來?? 操作系統(tǒng) 將 IP 地址返回給瀏覽器,同時自己也將 IP 地址 緩存 起來?? 至此, 瀏覽器 就得到了域名對應(yīng)的 IP 地址,并將 IP 地址 緩存 起來??

這些遠程查詢都是基于UDP協(xié)議,通常使用 53 號端口。
為什么選擇基于 UDP 協(xié)議發(fā)起 DNS 查詢,而不是 TCP?
衡量計算機通信快慢的指標是 響應(yīng)時間 ,即從用戶發(fā)出通信指令(輸入網(wǎng)址敲回車鍵)開始,到用戶看到完整頁面為止,所花費的時間。即:
響應(yīng)時間 = DNS域名解析時間 + TCP 連接建立時間 + HTTP交易時間
其中,TCP 連接建立需要三次揮手,HTTP交易一來一回,都不可能減少(具體計算過程可見 說一下HTTP/3新特性,為什么選擇使用UDP協(xié)議? ),所以只能讓DNS域名解析的時間越小越好
TCP
如果 DNS 查詢繼續(xù)采用 TCP 連接?TCP 作為可靠的傳輸協(xié)議,TCP 建立連接會帶來以下的額外開銷:
TCP 建立連接需要進行三次網(wǎng)絡(luò)通信; TCP 建立連接需要傳輸 ~130 字節(jié)的數(shù)據(jù); TCP 銷毀連接需要進行四次網(wǎng)絡(luò)通信; TCP 銷毀連接需要傳輸 ~160 字節(jié)的數(shù)據(jù);
假設(shè)網(wǎng)絡(luò)通信所消耗的時間是可以忽略的不計的,如果我們只考慮 TCP 建立連接時傳輸?shù)臄?shù)據(jù)的話,可以簡單來算一筆賬:

使用 TCP 協(xié)議(共 330 字節(jié)):
三次握手 — 14x3(Ethernet) + 20x3(IP) + 44 + 44 + 32 字節(jié) 查詢協(xié)議頭 — 14(Ethernet) + 20(IP) + 20(TCP) 字節(jié) 響應(yīng)協(xié)議頭 — 14(Ethernet) + 20(IP) + 20(TCP) 字節(jié)
需要注意的是,我們在這里計算結(jié)果的前提是 DNS 解析器只需要與一個命名服務(wù)器或者權(quán)威服務(wù)器進行通信就可以獲得 DNS 響應(yīng),但是在實際場景中,DNS 解析器可能會遞歸地與多個命名服務(wù)器進行通信,這也加倍地放大了 TCP 協(xié)議在額外開銷上的劣勢。
UDP
如果使用 UDP 協(xié)議(共 84 字節(jié))
查詢協(xié)議頭 — 14(Ethernet) + 20(IP) + 8(UDP) 字節(jié) 響應(yīng)協(xié)議頭 — 14(Ethernet) + 20(IP) + 8(UDP) 字節(jié)
如果 DNS 查詢的請求體和響應(yīng)分別是 15 和 70 字節(jié),那么 TCP 相比于 UDP 協(xié)議會增加 ~250 字節(jié)和 ~145% 的額外開銷
所以當請求體和響應(yīng)的大小比較小時,通過 TCP 協(xié)議進行傳輸不僅需要傳輸更多的數(shù)據(jù),還會消耗更多的資源,多次通信以及信息傳輸帶來的時間成本在 DNS 查詢較小時是無法被忽視的,TCP 連接帶來的可靠性在 DNS 的場景中沒能發(fā)揮太大的作用。
UDP 傳輸?shù)娜觞c
由于歷史的原因,互聯(lián)網(wǎng)上物理鏈路的最小 MTU = 576 ,基于 UDP 傳輸?shù)?DNS 為了限制報文不超過 576 ,所以將 DNS 報文限制在 512 字節(jié)。
這樣一旦 DNS 查詢應(yīng)答超過 512 字節(jié),基于 UDP 的 DNS 就只有截短為 512 字節(jié),那么用戶得到的 DNS 應(yīng)答就是不完整的。
為了克服這種困難,我們第一次在 DNS 協(xié)議中明確了 『當 DNS 查詢被截斷時,應(yīng)該使用 TCP 協(xié)議進行重試』 這一規(guī)范。盡管交易時間可能比較長,但畢竟可以得到完整的答案,總比得到不完整的答案要好。
同時,當數(shù)據(jù)包足夠大的時候,TCP 三次握手帶來的額外開銷比例就會越來越小,與整個包的大小相比就會趨近于 0:

RFC6891 中引入了 EDNS 機制,它允許我們使用 UDP 最多傳輸 4096 字節(jié)的數(shù)據(jù),但是由于 MTU 的限制導(dǎo)致的傳輸數(shù)據(jù)分片以及丟失(在實際生產(chǎn)中,一旦數(shù)據(jù)包中的數(shù)據(jù)超過了傳送鏈路的最大傳輸單元MTU,當前數(shù)據(jù)包就可能會被分片傳輸、丟棄),使得這一特性不夠可靠;
總結(jié)
需要注意的是,DNS 使用了 UDP 協(xié)議來獲取域名對應(yīng)的 IP 地址,這個沒錯,但有些片面,準確的來說,DNS 查詢在剛設(shè)計時主要使用 UDP 協(xié)議進行通信,而 TCP 協(xié)議也是在 DNS 的演進和發(fā)展中被加入到規(guī)范的:
DNS 在設(shè)計之初就在區(qū)域 傳輸中引入了 TCP 協(xié)議 , 在查詢中使用 UDP 協(xié)議 ,它同時占用了 UDP 和 TCP 的 53 端口 當 DNS 超過了 512 字節(jié)的限制,我們第一次在 DNS 協(xié)議中明確了 『當 DNS 查詢被截斷時,應(yīng)該使用 TCP 協(xié)議進行重試』 這一規(guī)范; 隨后引入的 EDNS 機制允許我們使用 UDP 最多傳輸 4096 字節(jié)的數(shù)據(jù),但是由于 MTU 的限制導(dǎo)致的數(shù)據(jù)分片以及丟失,使得這一特性不夠可靠; 在最近的幾年,我們重新規(guī)定了 DNS 應(yīng)該同時支持 UDP 和 TCP 協(xié)議,TCP 協(xié)議也不再只是重試時的選擇;
參考地址
極客時間透視 HTTP 協(xié)議 超詳細 DNS 協(xié)議解析:https://segmentfault.com/a/1190000039039275 為什么 DNS 使用 UDP 協(xié)議:https://draveness.me/whys-the-design-dns-udp-tcp/
你還有哪些補充嗎?或?qū)ξ闹杏腥魏萎愖h,歡迎提交至 https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/502 ,你的每一次反饋對我們都至關(guān)重要,感謝
如果感覺還不錯,歡迎點贊與在看,你的點贊與在看都是對我們最好的支持??
最近開源了一個github倉庫:百問百答,在工作中很難做到對社群問題進行立即解答,所以可以將問題提交至 https://github.com/Advanced-Frontend/Just-Now-QA ,我會在每晚花費 1 個小時左右進行處理,更多的是鼓勵與歡迎更多人一起參與探討與解答??
來自:https://github.com/Advanced-Frontend/Daily-Interview-Question
