你的域名是如何變成 IP 地址的?

detectiveHLH發表於2021-09-01

我的 個人網站 上線了,上面可以更好的檢索歷史文章,並且可以對文章進行留言,歡迎大家訪問

可能大家都知道或者被問過一個問題,那就是很經典的「從瀏覽器輸入 URL 再到頁面展示,都發生了什麼」。這個問題雖然簡單,但是真的能夠從回答的各種細節上看出不同人之間的水平差距。

這篇文章主要是聊一聊輸入 URL 之後的第一步——域名解析

域名就類似於 www.google.com,而通過 ping 命令,就可以查詢到對應域名的 IP 地址了。

那為什麼又要有域名,又要有 IP 呢?

域名、IP 共存

首先還是解釋一下,為什麼會出現現在這種域名、IP 地址共存的情況。主要有兩個點:

  1. 提升使用者體驗
  2. 提高執行效率

分別解釋一下,IP 地址長度為 32 位,平時用十進位制來表示的話,就長這樣——192.168.1.0 ,但是想象一下,如果我們要訪問某個網站需要讓我們輸入這麼一長串數字,體驗肯定相當差,首先記憶這麼長串數字對很多人來說就很痛苦,更何況我們常用的網站肯定不止一個。

除此之外,如果你給其他人推廣你的網站,你吧啦吧啦說了一大堆,然後來個「如果你感興趣,請訪問我們的網站 192.168.1.0」,然後就沒有然後了。

這也是為啥現在仍然在使用域名,方便人腦去記憶。

那為啥還需要 IP 地址呢?因為 IPv4 中的 IP 地址只需要 4 個位元組,而用字串表示的域名最少也需要幾十個位元組,長的甚至達到幾百位元組,而這會大大的增加底層路由器的負擔。

這也是為啥 IP 地址仍然在被使用。人來使用域名,而路由器層則使用 IP 地址,就跟我們書寫的是我們能認識的字元,而最終計算機認識的是一堆二進位制一樣。

DNS 解析

知道了這個背景之後,我們就可以來看看「域名」是如果變成「IP 地址」的。

首先我們知道,會往 DNS 伺服器傳送請求,那問題就來了,瀏覽器怎麼知道 DNS 伺服器的地址是啥?

答案是提前配置好的。當然這不是唯一的方式,DNS 也有可能通過 DHCP(Dynamic Host Configuration Protocol) 動態分配的。

例如,MacOS 中的 DNS 配置就長下面這樣。

當然,你也可以通過命令列來檢視、修改,地址在 /etc/resolv.conf

有了 DNS 伺服器,那麼你可能會覺得,接下來的事情就很簡單了:

我給你傳個域名,你返給我對應的 IP 地址即可。那問題來了,現在網際網路中有數萬臺的 DNS 伺服器,我怎麼知道資料在哪臺伺服器上?難道要一臺一臺的遍歷請求這數萬臺伺服器嗎?

我相信你肯定沒有感知到在瀏覽器中輸入域名到頁面展示會花費那麼久,這也說明肯定不是一臺一臺伺服器進行遍歷的。

域名的組成

要了解 DNS 是如何對其進行優化的,我們需要先知道域名的組成部分。看到這,很可能你會這麼想:

啥組成?不就是一堆字串嗎?

實際上,域名是有由不同的組成的,每個 . 隔開的部分就是一個

這裡舉個例子,假設我們分析的域名為 www.google.com ,從我們平時寫快遞的收貨地址的慣性思維來看,這個域的各個部分大小可能是這樣的:

www > google > com

但是實際上並不是這樣,而是:

. > com > google > www

你甚至發現,最大的還是個 . 。其實完整的域名應該是 www.google.com.. 代表根域,因為根域對於所有的域名來說,意義都一樣,所以平時我們都把最後的點給省略了。

每個域都有自己的專屬名詞:

. > com > google > www

根域 | 一級級域|二級域名|(子域名)|主機名

當然,我們知道還可以針對二級域名再劃分子域名,類似於 mail.google.com

所以看到這,你應該能夠理解域名是由層次的這個概念了,我再舉個比較的通俗的例子。

com 公司的 google 部門的 www。https://mail.google.com/mail/u/0/#inbox

DNS 的分層

瞭解完域名的分層之後,DNS 是如何優化域名解析的問題就迎刃而解了,那就是——分層。

DNS 伺服器會將域名的資料分散式的儲存在各個 DNS 伺服器上,但是同一個域的資料,會儲存在同一臺 DNS 伺服器上,同一臺 DNS 伺服器可以儲存多個域的資料。

這麼說可能會有些抽象,一圖勝千言,其實就是這樣:

有了對資料的分層,那麼查詢資料就會很有節奏感

查詢域名資料

一圖勝千言,有了分層的機制,整個的查詢過程就會長這樣:

首先會去配置的 DNS 伺服器中查詢,這個其實一般都是本地或者內網中的 DNS 伺服器。如果沒有找到,就會去問根域要,說哥們,我這裡需要 www.google.com 的 IP 地址。

根域一看,我這裡沒有啊,但是我知道 com 域的 DNS 伺服器地址,他可能知道。

然後 com 域的 DNS 伺服器一看,www.google.com 的 IP 地址我也不知道,但是我知道 google.com 域的 DNS 伺服器的地址,他可能知道,你再去問問他。

就這樣一路問下去,最終就能夠找到 www.google.com 所對應的 IP 地址了。

根域名伺服器

看了上面的流程,可能你還是會有點疑問。因為去找 DNS 伺服器查詢 IP 地址時,初始的 DNS 的伺服器的 IP 地址是走的本地計算機的配置的。那在分層查詢時,我怎麼知道有哪些根伺服器?以及我怎麼知道這些根伺服器的 IP 地址是啥?

答案是內建

我們的裝置,或者說所有能上網的裝置都會內建根伺服器的列表。總共有 13 臺根 DNS 伺服器,分別是[a-m].root-servers.net ,這些根伺服器的地址根本不需要查詢就能直接獲取。

當然,稍微想想也知道,13 臺伺服器是很難扛住全球網際網路使用者的請求的,實際上對於這 13 臺伺服器有很多的映象伺服器

眼見為實

說了這麼多虛的概念,接下來我們通過 dig 命令來實際操作一下。

可以看到,在 QUESTION SECTION 下的完整域名是 www.google.com. 是帶了根域的,那後面的這個 INA 又是啥意思呢?

這是因為,在向 DNS 伺服器查詢請求的時候,需要三個引數,分別是:

  1. 域名(例如 www.google.com)
  2. 網路型別(Class 設計之初,考慮到了多種網路並存的場景,但是目前實際上只有一種網路——網際網路,所以該引數的值一直都會為 —— IN
  3. 型別(例如 A 表示 IP 地址,而 MX 則表示郵件伺服器的地址)

而在 ANSWER SECTION 中,則是 DNS 服務的響應結果,上圖中顯示了總有 6 條 DNS 記錄,並且在後面返回了其對應的 IP 地址。

而其中的 69 則是 TTL,單位是秒,代表了在 69 之內都不用再次傳送請求了。

最下面則是統計的資訊,本次 DNS 查詢所話費的時間,以及請求的 DNS 伺服器的地址和埠。這個伺服器地址是我們本機配置的 DNS 伺服器的地址。

眼尖的可能發現了,上圖中根本沒有設計到對根伺服器的請求。這是因為這個命令把這部分給省略掉了,我們可能通過加上 +trace 命令列引數來檢視詳細的分級查詢過程

這次我們以 www.36kr.com 來作為例子。

可以看到,上圖中列出了所有的根域名伺服器,然後去找 com 域要,然後再找 36kr.com 域去要,最終是拿到了 www.36kr.com 的 IP 地址。

快取機制

當然,如果每次都從根伺服器開始往下找,明顯是不合理的,因為域名和 IP 地址的對應關係本來變動的就不頻繁,所以 DNS 伺服器是都會將結果快取的。

並且,在下圖中:

我只寫了一個 DNS 伺服器中有同級別的域資訊,但是實際上不同層級的域資訊可能存在於同一個 DNS 伺服器,舉個例子,com 域和 google.com 域可能在同一臺機器上。

但是,這個快取是有有效期的。如果在這個有效期內 DNS 資料發生了變化,那麼快取中的資料就會不正確,此時需要手動的將 DNS 刪除。

本篇文章已放到我的 Github github.com/sh-blog 中,歡迎 Star。微信搜尋關注【SH的全棧筆記】,回覆【佇列】獲取MQ學習資料,包含基礎概念解析和RocketMQ詳細的原始碼解析,持續更新中。

如果你覺得這篇文章對你有幫助,還麻煩點個贊關個注分個享留個言

相關文章