DNS 協議是什麼?完整查詢過程?爲何選擇使用 UDP 協議發起 DNS 查詢?

你可能瞭解 DNS 協議是什麼?那你瞭解 DNS 完整查詢過程是什麼嗎?它底層是基於 TCP 仍是 UDP 喃?TCP 與 UDP 又各自負責 DNS 的哪些部分喃?前端

引言

本文從如下幾個方面按部就班走進 DNS 協議、它的完整查詢過程以及底層是基於 UDP 仍是 TCP 實現?git

  • DNS 協議是什麼?
  • 域名結構
  • 域名解析緩存優化
  • DNS 查詢方式有哪些
  • DNS 完整查詢過程
  • 爲何選擇基於 UDP 協議發起 DNS 查詢,而不是 TCP?

DNS 協議是什麼?

DNS(Domain Name System:域名系統),與 HTTP、FTP 和 SMTP 同樣,DNS 協議也是應用層的協議,用於將用戶提供的主機名(域名)解析爲 IP 地址。github

簡單來講,DNS 就像是一個自動的電話號碼簿,咱們能夠直接撥打 47.105.127.0 呼叫對方,但這不方便記錄、記憶,DNS 提供一種手段可以讓咱們直接撥打對方的域名 www.pzijun.cn 找到對方面試

👆就是將域名 www.baidu.com 解析成 ip地址:1.1.1.1 ,思考一下🤔算法

  • DNS 如何根據域名解析成 IP 地址?

域名結構

DNS 的核心繫統是一個三層的樹狀、分佈式服務,基本對應域名的結構:segmentfault

  • 根域名服務器(Root DNS Server):管理頂級域名服務器,返回「com」「net」「cn」等頂級域名服務器的 IP 地址
  • 頂級域名服務器(Top-level DNS Server):管理各自域名下的權威域名服務器,好比 com 頂級域名服務器能夠返回 apple.com 域名服務器的 IP 地址
  • 權威域名服務器(Authoritative DNS Server):管理本身域名下主機的 IP 地址,好比 apple.com 權威域名服務器能夠返回 www.pzijun.cn 的 IP 地址

有了👆這個系統後,任何域名均可以在上面這個結構中進行從上到下查詢,例如,你要訪問「www.pzijun.cn」,就要進行下面的三次查詢:瀏覽器

  • 訪問根域名服務器,它會告訴你「cn」頂級域名服務器的地址;
  • 訪問「cn」頂級域名服務器,它再告訴你「pzijun.com」域名服務器的地址;
  • 最後訪問「pzijun.com」域名服務器,就獲得了「www.pzijun.cn」的地址

但若是全世界的域名解析都往這個系統裏擠,這個系統可能被擠癱瘓了,即便不癱瘓,解析速度也會大打折扣,因此 DNS 採起了一種很是有效的手段來解決這個問題: 緩存緩存

域名緩存優化

域名緩存有如下兩種方式:服務器

  • 非權威域名服務器(本地域名服務器)緩存 :各大運營服務商或大公司都有本身的 DNS 服務器,通常部署在距離用戶較近地方,代替用戶用戶訪問核心 DNS 系統,能夠緩存以前的查詢結果,若是已經有了記錄,就無需再向根服務器發起查詢,直接返回對應的 IP 地址
  • 本地計算機 DNS 記錄緩存
    • 瀏覽器緩存 :瀏覽器在獲取某一網站域名的實際 IP 地址後,進行緩存,以後遇到同一域名查詢以前的緩存結果便可,有效減小網絡請求的損耗。每種瀏覽器都有一個固定的 DNS 緩存時間,如 Chrome 的過時時間是 1 分鐘,在這個期限內不會從新請求 DNS
    • 操做系統緩存 :操做系統裏有一個特殊的「主機映射」文件,一般是一個可編輯的文本,在 Linux 裏是 /etc/hosts ,在 Windows 裏是 C:\WINDOWS\system32\drivers\etc\hosts ,若是操做系統在緩存裏找不到 DNS 記錄,就會找這個文件

DNS 查詢方式

DNS 查詢有兩種方式:遞歸迭代markdown

通常來講,DNS 客戶端設置使用的 DNS 服務器通常都是 遞歸服務器 ,它負責全權處理客戶端的 DNS 查詢請求,直到返回最終結果

而 DNS 根域名服務器之間通常採用 迭代查詢 方式,以避免根域名服務器的壓力過大

遞歸查詢

迭代查詢

DNS 完整查詢過程

將咱們上面所說的域名服務器之間的 DNS 查詢請求過程和域名緩存結合起來,完整查詢過程👇:

  1. 首先搜索 瀏覽器的 DNS 緩存 ,緩存中維護一張域名與 IP 地址的對應表
  2. 若是沒有命中😢,則繼續搜索 操做系統的 DNS 緩存
  3. 若是依然沒有命中🤦‍♀️,則操做系統將域名發送至 本地域名服務器 ,本地域名服務器查詢本身的 DNS 緩存,查找成功則返回結果(注意:主機和本地域名服務器之間的查詢方式是 遞歸查詢
  4. 若本地域名服務器的 DNS 緩存沒有命中🤦‍,則本地域名服務器向上級域名服務器進行查詢,經過如下方式進行 迭代查詢 (注意:本地域名服務器和其餘域名服務器之間的查詢方式是迭代查詢,防止根域名服務器壓力過大):
  • 首先本地域名服務器向根域名服務器發起請求,根域名服務器是最高層次的,它並不會直接指明這個域名對應的 IP 地址,而是返回頂級域名服務器的地址,也就是說給本地域名服務器指明一條道路,讓他去這裏尋找答案
  • 本地域名服務器拿到這個頂級域名服務器的地址後,就向其發起請求,獲取權限域名服務器的地址
  • 本地域名服務器根據權限域名服務器的地址向其發起請求,最終獲得該域名對應的 IP 地址
  1. 本地域名服務器 將獲得的 IP 地址返回給操做系統,同時本身將 IP 地址 緩存 起來📝
  2. 操做系統 將 IP 地址返回給瀏覽器,同時本身也將 IP 地址 緩存 起來📝
  3. 至此, 瀏覽器 就獲得了域名對應的 IP 地址,並將 IP 地址 緩存 起來📝

這些遠程查詢都是基於UDP協議,一般使用 53 號端口。

爲何選擇基於 UDP 協議發起 DNS 查詢,而不是 TCP?

衡量計算機通訊快慢的指標是 響應時間 ,即從用戶發出通訊指令(輸入網址敲回車鍵)開始,到用戶看到完整頁面爲止,所花費的時間。即:

響應時間 = DNS域名解析時間 + TCP 鏈接創建時間 + HTTP交易時間

其中,TCP 鏈接創建須要三次揮手,HTTP交易一來一回,都不可能減小(具體計算過程可見 說一下HTTP/3新特性,爲何選擇使用UDP協議? ),因此只能讓DNS域名解析的時間越小越好

TCP

若是 DNS 查詢繼續採用 TCP 鏈接?TCP 做爲可靠的傳輸協議,TCP 創建鏈接會帶來如下的額外開銷:

  • TCP 創建鏈接須要進行三次網絡通訊;
  • TCP 創建鏈接須要傳輸 ~130 字節的數據;
  • TCP 銷燬鏈接須要進行四次網絡通訊;
  • TCP 銷燬鏈接須要傳輸 ~160 字節的數據;

假設網絡通訊所消耗的時間是能夠忽略的不計的,若是咱們只考慮 TCP 創建鏈接時傳輸的數據的話,能夠簡單來算一筆帳:

使用 TCP 協議(共 330 字節):

  • 三次握手 — 14x3(Ethernet) + 20x3(IP) + 44 + 44 + 32 字節
  • 查詢協議頭 — 14(Ethernet) + 20(IP) + 20(TCP) 字節
  • 響應協議頭 — 14(Ethernet) + 20(IP) + 20(TCP) 字節

須要注意的是,咱們在這裏計算結果的前提是 DNS 解析器只須要與一個命名服務器或者權威服務器進行通訊就能夠得到 DNS 響應,可是在實際場景中,DNS 解析器可能會遞歸地與多個命名服務器進行通訊,這也加倍地放大了 TCP 協議在額外開銷上的劣勢。

UDP

若是使用 UDP 協議(共 84 字節)

  • 查詢協議頭 — 14(Ethernet) + 20(IP) + 8(UDP) 字節
  • 響應協議頭 — 14(Ethernet) + 20(IP) + 8(UDP) 字節

若是 DNS 查詢的請求體和響應分別是 15 和 70 字節,那麼 TCP 相比於 UDP 協議會增長 ~250 字節和 ~145% 的額外開銷

因此當請求體和響應的大小比較小時,經過 TCP 協議進行傳輸不只須要傳輸更多的數據,還會消耗更多的資源,屢次通訊以及信息傳輸帶來的時間成本在 DNS 查詢較小時是沒法被忽視的,TCP 鏈接帶來的可靠性在 DNS 的場景中沒能發揮太大的做用。

UDP 傳輸的弱點

因爲歷史的緣由,互聯網上物理鏈路的最小 MTU = 576 ,基於 UDP 傳輸的 DNS 爲了限制報文不超過 576 ,因此將 DNS 報文限制在 512 字節。

這樣一旦 DNS 查詢應答超過 512 字節,基於 UDP 的 DNS 就只有截短爲 512 字節,那麼用戶獲得的 DNS 應答就是不完整的。

爲了克服這種困難,咱們第一次在 DNS 協議中明確了 『當 DNS 查詢被截斷時,應該使用 TCP 協議進行重試』 這一規範。儘管交易時間可能比較長,但畢竟能夠獲得完整的答案,總比獲得不完整的答案要好。

同時,當數據包足夠大的時候,TCP 三次握手帶來的額外開銷比例就會愈來愈小,與整個包的大小相比就會趨近於 0:

RFC6891 中引入了 EDNS 機制,它容許咱們使用 UDP 最多傳輸 4096 字節的數據,可是因爲 MTU 的限制致使的傳輸數據分片以及丟失(在實際生產中,一旦數據包中的數據超過了傳送鏈路的最大傳輸單元MTU,當前數據包就可能會被分片傳輸、丟棄),使得這一特性不夠可靠;

總結

須要注意的是,DNS 使用了 UDP 協議來獲取域名對應的 IP 地址,這個沒錯,但有些片面,準確的來講,DNS 查詢在剛設計時主要使用 UDP 協議進行通訊,而 TCP 協議也是在 DNS 的演進和發展中被加入到規範的:

  1. DNS 在設計之初就在區域 傳輸中引入了 TCP 協議在查詢中使用 UDP 協議 ,它同時佔用了 UDP 和 TCP 的 53 端口
  2. 當 DNS 超過了 512 字節的限制,咱們第一次在 DNS 協議中明確了 『當 DNS 查詢被截斷時,應該使用 TCP 協議進行重試』 這一規範;
  3. 隨後引入的 EDNS 機制容許咱們使用 UDP 最多傳輸 4096 字節的數據,可是因爲 MTU 的限制致使的數據分片以及丟失,使得這一特性不夠可靠;
  4. 在最近的幾年,咱們從新規定了 DNS 應該同時支持 UDP 和 TCP 協議,TCP 協議也再也不只是重試時的選擇;

參考地址

天天三分鐘,進階一個前端小 tip 面試題庫 算法題庫

相關文章
相關標籤/搜索