?? 盡人事,聽天命,博主東南大學研究生在讀,熱愛健身和籃球,正在為兩年后的秋招準備中,樂于分享技術相關的所見所得,關注公眾號 @ 飛天小牛肉,第一時間獲取文章更新,成長的路上我們一起進步
?? 本文已收錄于 CS-Wiki(Gitee 官方推薦專案,現已 0.9k star),致力打造完善的后端知識體系,在技術的路上少走彎路,歡迎各位小伙伴前來交流學習
0. 前言
為了保證網址的正常訪問,域名決議協議(DNS)其實在背后做出了很多努力,本文將透徹講解 DNS 協議的原理,了解我們每天都在接觸的網址到底是怎么作業的,

1. 什么是 DNS 協議
在學習 DNS 協議之前,我們先區分一下域名和 IP 地址這個兩個概念:
- IP 地址:一長串能夠唯一地標記網路上的計算機的數字
- 域名:又稱網域,是由一串用點分隔的名字組成的 Internet 上某一臺計算機或計算機組的名稱,用于在資料傳輸時對計算機的定位標識(有時也指地理位置)比如
www.baidu.com
不知道有沒有同學會混淆域名和網址的概念,可以這樣理解,網址里面含有域名,舉個例子:
www.gitee.com/veal98就是一個網址,而www.gitee.com就是域名
由于 IP 地址具有不方便記憶并且不能顯示地址組織的名稱和性質等缺點,人們設計出了域名,并通過域名決議協議(DNS,Domain Name System)來將域名和 IP 地址相互映射,使人更方便地訪問互聯網,而不用去記住能夠被機器直接讀取的 IP 地址數串,將域名映射成 IP 地址稱為正向決議,將 IP 地址映射成域名稱為反向決議,
?? DNS 協議可以使用 UDP 或者 TCP 進行傳輸,使用的埠號都為 53,但大多數情況下 DNS 都使用 UDP 進行傳輸,
2. 域名詳解
? 那么域名由誰來規定和管理呢?不能是隨便寫吧?
全世界域名的最高管理機構,是一個叫做 ICANN (Internet Corporation for Assigned Names and Numbers)的組織,總部在美國加州,ICANN 負責管理全世界域名系統的運作,

域名其實是具有一定的層次結構的,從上到下依次為:根域名、頂級域名(top level domain,TLD)、二級域名、(三級域名)

① 頂級域名
先來講講頂級域名(TLD),即最高層級的域名,簡單說,就是網址的最后一個部分,比如,網址www.baidu.com 的頂級域名就是 .com,ICANN 的一項主要作業,就是規定哪些字串可以當作頂級域名,截至 2015 年 7 月,頂級域名共有 1058 個,它們大致可以分成兩類:
- 一類是通用頂級域名(gTLD),比如
.com、.net、.edu、.org、.xxx等等,共有 700 多個, - 另一類是國家頂級域名(ccTLD),代表不同的國家和地區,比如
.cn(中國)、.io(英屬印度洋領地)、.cc( 科科斯群島)、.tv(圖瓦盧)等,共有 300 多個,
當然,ICANN 自己不會去管理這些頂級域名,因為根本管不過來,想想看,頂級域名有1000多個,每個頂級域名下面都有許多批發商,如果每個都要管,就太麻煩了,ICANN 的政策是,每個頂級域名都找一個托管商,該域名的所有事項都由托管商負責,ICANN 只與托管商聯系,這樣管理起來就容易多了,舉例來說,.cn 國家頂級域名的托管商就是中國互聯網路資訊中心(CNNIC),它決定了 .cn 域名的各種政策,
② 二級域名
而二級域名(Second Level Domain,SLD) 在通用頂級域名或國家頂級域名之下具有不同的意義:
- 通用頂級域名下的二級域名:一般是指域名注冊人選擇使用的網上名稱,如
yahoo.com(商業組織通常使用自己的商標、商號或其他商業標志作為自己的網上名稱,如baidu.com) - 國家頂級域名下的二級域名:一般是指類似于通用頂級域名的表示注冊人類別和功能的標志,例如,在
.com.cn域名結構中,.com此時是置于國家頂級域名.cn下的二級域名,表示中國的商業性組織,以此類推,
三級域名是形如 www.baidu.com 的域名,可以當做是二級域名的子域名,特征為域名包含兩個 .,對于域名所有者/使用者而言,三級域名都是二級域名的附屬物而無需單獨費用,三級域名甚至不能稱為域名,一般稱之為域名下的 “二級目錄”,
③ 根域名
? 那么根域名在哪里呢?在層次結構中根域名不是最頂級的嗎?域名中怎么沒有看見它?
由于 ICANN 管理著所有的頂級域名,所以它是最高一級的域名節點,被稱為根域名(root domain),在有些場合,www.xxx.com 被寫成 www.xxx.com.,即最后還會多出一個點,這個點就是根域名,

理論上,所有域名的查詢都必須先查詢根域名,因為只有根域名才能告訴你,某個頂級域名由哪臺服務器管理,事實上也確實如此,ICANN 維護著一張串列(根域名串列),里面記載著頂級域名和對應的托管商,

比如,我要訪問abc.xyz,也必須先去詢問根域名串列,它會告訴我 .xyz 域名由 CentralNic 公司托管,根域名串列還記載,.google由谷歌公司托管,.apple由蘋果公司托管等等,
由于根域名串列很少變化,大多數 DNS 服務商都會提供它的快取,所以根域名的查詢事實上不是那么頻繁,
3. 域名服務器詳解
域名服務器是指管理域名的主機和相應的軟體,它可以管理所在分層的域的相關資訊,一個域名服務器所負責管里的分層叫作 區 (ZONE),域名的每層都設有一個域名服務器:
- 根域名服務器
- 頂級域名服務器
- 權限域名服務器
下面這幅圖就很直觀了:

除了上面三種 DNS 服務器,還有一種不在 DNS 層次結構之中,但是很重要的 DNS 服務器,即本地域名服務器,下面我們分別講解這四種服務器都是用來干什么的 ??
① 根域名服務器
上面我們提到,ICANN 維護著一張根域名串列,里面記載著頂級域名和對應的托管商,其實根域名串列的正式名稱是 DNS 根區(DNS root zone),保存 DNS 根區檔案的服務器,就叫做 DNS 根域名服務器(root name server),根域名服務器保存所有的頂級域名服務器的地址
由于早期的 DNS 查詢結果是一個 512 位元組的 UDP 資料包,這個包最多可以容納 13 個服務器的地址,因此就規定全世界有 13 個根域名服務器,編號從 a.root-servers.net 一直到 m.root-servers.net,其中 10 臺設定在美國,另外各有一臺設定于荷蘭、瑞典和日本,
前面我們說過,理論上所有域名的查詢都必須先查詢根域名,所以一般來說所有的域名服務器都會注冊一份根域名服務器的 IP 地址的快取,用于在必要的時候向其發送請求,
② 頂級域名服務器
按照根域名服務器管理頂級域名的邏輯,頂級域名服務器顯然就是用來管理注冊在該頂級域名下的所有二級域名的,記錄這些二級域名的 IP 地址,
③ 權限域名服務器
按照上面的邏輯,權限域名服務器應該是管理注冊在二級域名下的所有三/四級域名的,但其實不是這樣,如果一個二級域名或者一個三/四級域名對應一個域名服務器,則域名服務器數量會很多,我們需要使用劃磁區的辦法來解決這個問題,那么權限域名服務器就是負責管理一個“區”的域名服務器,
? 什么是區?怎樣劃磁區呢?
區和域其實是不同的,區可以有多種不同的劃分方法,以百度為例,我們假設有 fanyi.baidu.com、ai.baidu.com、tieba.baidu.com 這三個三級域名,我們可以這樣磁區,fanyi.baidu.com 和 tieba.baidu.com 放在 baidu.com 權限域名服務器,ai.baidu.com 放在 ai.baidu.com 權限域名服務器中,并且 baidu.com 權限域名服務器和 ai.baidu.com 權限域名服務器是同等地位的,而具體怎么磁區是百度公司根據域名多少、訪問多少等情況去自己規定的,
畫個圖直觀理解一下:

④ 本地域名服務器
除了上面三種 DNS 服務器,還有一種不在 DNS 層次結構之中,但是很重要的 DNS 服務器,就是本地域名服務器(也被稱為權威域名服務器),本地域名服務器是電腦決議時的默認域名服務器,即電腦中設定的首選 DNS 服務器和備選 DNS 服務器,常見的有電信、聯通、谷歌、阿里等的本地 DNS 服務,

每個因特網服務提供者或一所大學,甚至一所大學中的各個系,都可以擁有一個本地域名服務器,當一臺主機發出 DNS 查詢請求時,這個查詢請求報文就發送給該主機的本地域名服務器,本地域名服務器管理本地域名的決議和映射,并且能夠向上級域名服務器進行查詢,
那么具體本地域名服務器是如何向上級域名服務器轉發查詢請求的呢?
4. DNS 查詢方式
具體 DNS 查詢的方式有兩種:
- 遞回查詢
- 迭代查詢
所謂迭代就是,如果請求的接收者不知道所請求的內容,那么接收者將扮演請求者,發出有關請求,直到獲得所需要的內容,然后將內容回傳給最初的請求者,
?? 通俗點來說,在遞回查詢中,如果 A 請求 B,那么 B 作為請求的接收者一定要給 A 想要的答案;而迭代查詢則是指,如果接收者 B 沒有請求者 A 所需要的準確內容,接收者 B 將告訴請求者 A,如何去獲得這個內容,但是自己并不去發出請求,
一般來說,域名服務器之間的查詢使用迭代查詢方式,以免根域名服務器的壓力過大,通過下面這兩個圖就能很好的理解了 ??
1)遞回查詢:

2)迭代查詢:

5. 域名快取
上面講解的是域名服務器之間的 DNS 查詢請求程序,但實際上,每個時刻都有無數網民要上網,那每次都去訪問本地域名服務器去獲取 IP 地址顯然是不實際的,解決方法就是使用快取保存域名和 IP 地址的映射,
計算機中 DNS 記錄在本地有兩種快取方式:瀏覽器快取和作業系統快取,
1)瀏覽器快取:瀏覽器在獲取網站域名的實際 IP 地址后會對其進行快取,減少網路請求的損耗,每種瀏覽器都有一個固定的 DNS 快取時間,如 Chrome 的過期時間是 1 分鐘,在這個期限內不會重新請求 DNS
2)作業系統快取:作業系統的快取其實是用戶自己配置的 hosts 檔案,比如 Windows10 下的 hosts 檔案存放在 C:\Windows\System32\drivers\etc\hosts

Windows 系統默認開啟 DNS 快取服務,服務名是 DNSClient,可以快取一些常用的域名,

使用命令 ipconfig/displaydns 可以查看電腦中快取的域名,

? 在瀏覽器中進行訪問的時候,會優先查詢瀏覽器快取,如果未命中則繼續查詢作業系統快取,最后再查詢本地域名服務器,然后本地域名服務器會遞回的查找域名記錄,最后回傳結果,主機和本地域名服務器之間的查詢方式是遞回查詢,也就是說主機請求本地域名服務器,那么本地域名服務器作為請求的接收者一定要給主機想要的答案,
6. 完整域名決議程序
OK,將我們上面所說的域名服務器之間的 DNS 查詢請求程序和域名快取結合起來,就是一個完整的 DNS 協議進行域名決議的程序,這里我們以正向決議為例(域名決議成 IP 地址):
1)首先搜索瀏覽器的 DNS 快取,快取中維護一張域名與 IP 地址的對應表;
2)若沒有命中,則繼續搜索作業系統的 DNS 快取;
3)若仍然沒有命中,則作業系統將域名發送至本地域名服務器,本地域名服務器查詢自己的 DNS 快取,查找成功則回傳結果(注意:主機和本地域名服務器之間的查詢方式是遞回查詢);
4)若本地域名服務器的 DNS 快取沒有命中,則本地域名服務器向上級域名服務器進行查詢,通過以下方式進行迭代查詢(注意:本地域名服務器和其他域名服務器之間的查詢方式是迭代查詢,防止根域名服務器壓力過大):
- 首先本地域名服務器向根域名服務器發起請求,根域名服務器是最高層次的,它并不會直接指明這個域名對應的 IP 地址,而是回傳頂級域名服務器的地址,也就是說給本地域名服務器指明一條道路,讓他去這里尋找答案
- 本地域名服務器拿到這個頂級域名服務器的地址后,就向其發起請求,獲取權限域名服務器的地址
- 本地域名服務器根據權限域名服務器的地址向其發起請求,最終得到該域名對應的 IP 地址
4)本地域名服務器將得到的 IP 地址回傳給作業系統,同時自己將 IP 地址快取起來
5)作業系統將 IP 地址回傳給瀏覽器,同時自己也將 IP 地址快取起來
6)至此,瀏覽器就得到了域名對應的 IP 地址,并將 IP 地址快取起來
配合下圖直觀理解:

?? 關注公眾號 | 飛天小牛肉,即時獲取更新
- 博主東南大學研究生在讀,利用課余時間運營一個公眾號『 飛天小牛肉 』,2020/12/29 日第一次開通,專注分享計算機基礎(資料結構 + 演算法 + 計算機網路 + 資料庫 + 作業系統 + Linux)、Java 基礎和面試指南的相關原創技術好文,本公眾號的目的就是讓大家可以快速掌握重點知識,有的放矢,希望大家多多支持哦,和小牛肉一起成長 ??
- 并推薦個人維護的開源教程類專案: CS-Wiki(Gitee 推薦專案,現已 0.9k star), 致力打造完善的后端知識體系,在技術的路上少走彎路,歡迎各位小伙伴前來交流學習 ~ ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/259100.html
標籤:其他
上一篇:在QT C++中呼叫 Python并將軟體打包發布(裸機可運行)
下一篇:基于資料庫的代碼自動生成工具,生成JavaBean、生成資料庫檔案、生成前后端代碼等(TableGo v7.0.0版)
