為什么要有DNS
如果我們想要訪問(wèn)某度,你可以在瀏覽器上的搜索欄里輸入112.80.248.76這個(gè)IP地址,直達(dá)頁(yè)面。
通過(guò)IP訪問(wèn)網(wǎng)頁(yè)
這樣的行為,合法,但有病 。
大部分人,連自己對(duì)象的電話號(hào)碼都記不住,又怎么可能記得住這么一串IP地址呢。
哦,不好意思,傷害到兄弟們了,你們沒(méi)對(duì)象。
但我假設(shè)你們有。
回想一下,雖然你記不住對(duì)象的電話號(hào)碼,但卻不影響你給她打電話。你的操作過(guò)程是不是打開(kāi)通訊錄 ,輸入"富婆",然后就彈出一個(gè)電話號(hào)碼。點(diǎn)擊即撥打。
在計(jì)算機(jī)領(lǐng)域,你大概率也記不住IP,所以也需要有類似的通訊錄的功能 。比如,你只需要輸入www.baidu.com,它就能幫你找到對(duì)應(yīng)的 112.80.248.76,然后進(jìn)行訪問(wèn)。
用域名訪問(wèn)
其中www.baidu.com 是域名 ,通過(guò)這個(gè)域名可以獲得它背后的IP是112.80.248.76。
就像一個(gè)人可以有多個(gè)電話號(hào)碼一樣,一個(gè)域名也可以對(duì)應(yīng)有多個(gè)IP地址。
而將域名解析為IP的過(guò)程,也就是查"通訊錄"的過(guò)程 ,其實(shí)就是DNS (D omain N ame S ystem,域名系統(tǒng))協(xié)議需要做的事情。
另外需要注意的是,上面的這個(gè)IP地址,我寫這篇文章的時(shí)候能訪問(wèn),不代表大家看文章的時(shí)候能訪問(wèn)。因?yàn)檫@背后的IP地址是有可能變更的??梢酝ㄟ^(guò)使用 ping www.baidu.com獲得最新的IP地址。
ping獲得IP
但問(wèn)題就來(lái)了。
普通人的通訊錄,一般有一千個(gè)電話號(hào)碼就算是社交小達(dá)人 了,放在通訊錄里綽綽有余。
然而網(wǎng)站域名,卻不一樣,據(jù)說(shuō)2015年的時(shí)候就已經(jīng)超過(guò)3億了。
如果將這3億條記錄都放在一個(gè)服務(wù)器里,會(huì)有兩個(gè)問(wèn)題 。
? 超過(guò)3億條域名數(shù)據(jù),數(shù)據(jù)量過(guò)大 ,并且數(shù)據(jù)量持續(xù)增加
? 需要承受大量的讀請(qǐng)求 。每個(gè)網(wǎng)站域名都可能會(huì)有成千的訪問(wèn)。這加起來(lái),四舍五入也有千億qps了。
顯然,如果將DNS做成類似手機(jī)通訊錄這樣的單點(diǎn)服務(wù),那是不可能實(shí)現(xiàn)這樣的能力的,必須得是分布式系統(tǒng) 。
于是,問(wèn)題就變成了,如何設(shè)計(jì)一個(gè)支持千億+qps請(qǐng)求的大型分布式系統(tǒng) 。
我知道肯定有人要說(shuō):"這是服務(wù)只有10qps的人該考慮的事情嗎?"
雖然我們做的服務(wù)可能只有10qps,但這并不妨礙我們學(xué)習(xí)DNS里優(yōu)秀的設(shè)計(jì)。
我們就從URL的層次結(jié)構(gòu)聊起。
URL的層次結(jié)構(gòu)
舉個(gè)例子。一個(gè)常見(jiàn)的域名,比如 www.baidu.com。
可以看到,這個(gè)域名中間用了兩個(gè)句點(diǎn) 。通過(guò)句點(diǎn)符號(hào),可以將域名分為三部分。
其中com被稱為一級(jí)域 或頂級(jí)域 ,其他常見(jiàn)的頂級(jí)域還有cn,co等,baidu是二級(jí)域 ,www則是三級(jí)域 。
除此之后,在com后面,其實(shí)還有一個(gè)被省略掉的句點(diǎn)號(hào) 。它叫根域 。
域名的層次結(jié)構(gòu)
當(dāng)域名多起來(lái)了之后,將它們相同的部分抽取出來(lái),多個(gè)域名就可以變成這樣的樹(shù)狀層級(jí)結(jié)構(gòu) 。
層次結(jié)構(gòu)
這時(shí)候我們就可以看到,這些域之間其實(shí)是一種層級(jí)關(guān)系 ,就像是學(xué)校,年級(jí),班級(jí)那樣。
當(dāng)你想要去定位一個(gè)具體域名的時(shí)候,你就可以通過(guò)這樣的層級(jí)找到對(duì)應(yīng)的域名。
舉個(gè)例子。大家應(yīng)該還記得那句廣告詞,"三年級(jí)2班的李小明同學(xué),你媽媽拿了兩罐旺仔牛奶給你",其實(shí)李小明的媽媽,就是通過(guò),學(xué)校、年級(jí)、班級(jí)的層級(jí)形式,一層層找到人。
DNS的原理
我們重新回來(lái)看下大佬們是怎么設(shè)計(jì)DNS。
先直接說(shuō)最重要的結(jié)論。
? 利用層級(jí)結(jié)構(gòu)去拆分服務(wù)
? 加入多級(jí)緩存
接下來(lái)展開(kāi)。
利用URL層級(jí)結(jié)構(gòu)去拆分服務(wù)
DNS承載的流量壓力非常大,必須要做成分布式服務(wù) ,于是問(wèn)題的關(guān)鍵就變成了如何拆分服務(wù) 。
既然URL是樹(shù)狀的層級(jí)結(jié)構(gòu),那保存它們的服務(wù),也可以依據(jù)這個(gè),非常自然的拆成樹(shù)狀的形式。
一臺(tái)服務(wù)器維護(hù)一個(gè)或多個(gè)域的信息。于是服務(wù)就變成了下面這樣的層級(jí)形式。
當(dāng)我們需要訪問(wèn)www.baidu.com。
查詢過(guò)程就跟下圖一樣。
DNS查詢過(guò)程
請(qǐng)求會(huì)先打到最近的DNS服務(wù)器(比如你家的家用路由器)中,如果在DNS服務(wù)器中找不到,則DNS服務(wù)器會(huì)直接詢問(wèn)根域服務(wù)器,在根域服務(wù)器中雖然沒(méi)有www.baidu.com這條記錄的,但它可以知道這個(gè)URL屬于com域,于是就找到com域服務(wù)器的IP地址,然后訪問(wèn)com域服務(wù)器,重復(fù)上面的操作,再找到放了baidu域的服務(wù)器是哪個(gè),繼續(xù)往下,直到找到www.baidu.com的那條記錄,最后返回對(duì)應(yīng)的IP地址。
可以看到,原理比較簡(jiǎn)單,但這里涉及到兩個(gè)問(wèn)題。
? 本機(jī)怎么知道最近的DNS服務(wù)器IP是什么?
? 最近的DNS服務(wù)器怎么知道根域的IP是多少?
我們一個(gè)個(gè)來(lái)回答。
本機(jī)怎么知道最近的DNS服務(wù)器的IP是什么?
這個(gè)在之前寫過(guò)的《剛插上網(wǎng)線,電腦怎么知道自己的IP是什么?》 提到過(guò),插上網(wǎng)線時(shí),機(jī)子會(huì)通過(guò)DHCP協(xié)議獲得本機(jī)的IP地址,子網(wǎng)掩碼,路由器地址,以及DNS服務(wù)器的IP地址 。
DHCP協(xié)議
下面是我的mac機(jī)子,第二階段DHCP Offer中的抓包截圖??梢钥吹剑@里面返回的信息里包含了DNS服務(wù)器的IP 。
offer階段
同時(shí)也可以在左上角的點(diǎn)左上角的蘋果圖標(biāo)->系統(tǒng)表偏好設(shè)置->網(wǎng)絡(luò)->高級(jí)->DNS中查看到DNS服務(wù)器的IP地址。
這里有個(gè)小細(xì)節(jié),從上面的抓包圖里可以看到路由器地址和DNS服務(wù)器地址,以及DHCP服務(wù)器地址 ,其實(shí)都是192.168.31.1,這個(gè)其實(shí)是我這邊的家用路由器 的IP地址,也就是說(shuō)一般家用路由器自帶這幾個(gè)功能。
而在某里云服務(wù)器里,DNS服務(wù)器也是一樣,是通過(guò)dhcp協(xié)議獲得。查看DNS服務(wù)器的IP地址也很方便,執(zhí)行cat /etc/resolv.conf就好了。
這上面的nameserver中,可以看出有兩臺(tái)DNS服務(wù)器,機(jī)子會(huì)按照文件中出現(xiàn)的順序來(lái)發(fā)起請(qǐng)求,如果第一臺(tái)服務(wù)器沒(méi)反應(yīng),就會(huì)去請(qǐng)求第二臺(tái)。
最近的DNS服務(wù)器怎么知道根域的IP是多少?
我們也知道根域,就是域名樹(shù)的頂層,既然是頂層,那信息一般也就相對(duì)少一些。對(duì)應(yīng)的IPV4地址只有13個(gè),IPV6地址只有25個(gè)。
我們可以通過(guò)dig命令的+trace選項(xiàng)來(lái)查看一個(gè)域名的dns解析過(guò)程。
而前面提到的傳說(shuō)中的13個(gè)根域,從字母a-m,就都在上圖中。
但這又引發(fā)了一個(gè)問(wèn)題,上面看到的都是域名。
這。。。
"我本來(lái)是想通過(guò)域名去找IP的,你又讓我去找其他域名的IP?"
聽(tīng)起來(lái)不科學(xué),這不就死循環(huán) 了嗎。
是的,所以這些根域名對(duì)應(yīng)的IP會(huì)以配置文件的形式,放在每個(gè) 域名服務(wù)器中。
也就是說(shuō)并不需要再去請(qǐng)求根域名對(duì)應(yīng)的IP ,直接在配置里能讀出來(lái)就好了。
下面這個(gè)截圖是域名服務(wù)器里的配置內(nèi)容。
可以看到A開(kāi)頭的根域,它的IPV4地址是198.41.0.4。
加入多級(jí)緩存
對(duì)于高并發(fā)讀多寫少的場(chǎng)景,加入緩存幾乎就是標(biāo)配。
DNS也不例外,它加了緩存,而且不止一層。
從在瀏覽器的搜索框中輸入U(xiǎn)RL。它會(huì)先后訪問(wèn)瀏覽器緩存 、操作系統(tǒng)的緩存 /etc/hosts、最近的DNS服務(wù)器緩存 。如果都找不到,才是到根域,頂級(jí)(一級(jí))域,二級(jí)域等DNS服務(wù)器進(jìn)行查詢請(qǐng)求。
加入緩存后的DNS查詢順序
于是請(qǐng)求過(guò)程就成了下圖這樣??梢钥吹缴厦嫣岬降暮脦子芯彺娴牡胤轿叶技恿藗€(gè)綠色的小文件圖標(biāo),優(yōu)先在緩存里做查詢。
加入緩存后的DNS查詢過(guò)程
由于緩存了上面樹(shù)狀結(jié)構(gòu)的信息,最近的DNS服務(wù)器也不再需要每次都從根域 開(kāi)始查起。比如在緩存里能找到baidu.com的服務(wù)器IP,就直接跳到二級(jí)域服務(wù)器上做查找就好了。
正因?yàn)槎嗉?jí)緩存的存在,每一層實(shí)際接收到的請(qǐng)求都大大減少了。并且每個(gè)人日常訪問(wèn)的網(wǎng)站也就那么幾個(gè),所以大部分時(shí)候都能命中緩存直接返回IP地址。
簡(jiǎn)單小結(jié)下。
DNS的設(shè)計(jì)中,通過(guò)層次結(jié)構(gòu)將服務(wù)進(jìn)行拆分 ,流量分散到多個(gè)服務(wù)器中。
又通過(guò)加入多級(jí)緩存 ,讓每個(gè)層級(jí)實(shí)際接收到的請(qǐng)求大大減少,因此大大提高了系統(tǒng)的性能。
這兩點(diǎn) ,是我們做業(yè)務(wù)開(kāi)發(fā)的過(guò)程中可以參考的優(yōu)秀設(shè)計(jì)。
但還有一點(diǎn) ,是我們大概率學(xué)不來(lái)的,叫任播 ,它也為DNS實(shí)現(xiàn)高并發(fā)處理能力提供了重要支持,我會(huì)把它放到放到下一篇文章展開(kāi)聊聊。
協(xié)議格式
DNS是個(gè)域名解析系統(tǒng),而運(yùn)行在這套系統(tǒng)上的協(xié)議,就叫DNS協(xié)議 。
和HTTP類似,DNS協(xié)議也是個(gè)應(yīng)用層協(xié)議 。
DNS是應(yīng)用層協(xié)議
下圖是它的報(bào)文格式。
DNS報(bào)文
字段太多,很暈?這就對(duì)了。
我們就挑幾個(gè)重點(diǎn)的說(shuō)說(shuō)。
Transsaction ID 是事務(wù)ID,對(duì)于一次請(qǐng)求 和這個(gè)請(qǐng)求對(duì)應(yīng)的應(yīng)答 ,他們的事務(wù)ID是一樣的,類似于微服務(wù)系統(tǒng)中的log_id。
flag字段 是指標(biāo)志位,有2個(gè)Byte,16個(gè)bit,需要關(guān)注的是QR,OpCode, RCode。
? QR 用來(lái)標(biāo)志這是個(gè)查詢還是響應(yīng)報(bào)文,0是查詢,1是響應(yīng)。
? OpCode 用來(lái)標(biāo)志操作碼,正常查詢都是0,不管是域名查ip,還是ip查域名,都屬于正常查詢 。可以粗暴的認(rèn)為我們平時(shí)只會(huì)看到0。
? RCode 是響應(yīng)碼,類似于HTTP里的404, 502 這樣的status code。用來(lái)表示這次請(qǐng)求的結(jié)果是否正常。0是指一切正常。1是指報(bào)文格式錯(cuò)誤,2服務(wù)域名服務(wù)器內(nèi)部錯(cuò)誤。
Queries 字段,是指你實(shí)際查詢的內(nèi)容。這里其實(shí)包含三部分信息,Name, Type, Class。
查詢的內(nèi)容分成三部分信息
? Name 可以放域名或者IP。比如你要查的是baidu.com這個(gè)域名對(duì)應(yīng)的IP,那里面放的就是域名 ,反過(guò)來(lái)通過(guò)IP查對(duì)應(yīng)的域名,那Name字段里放的就是IP 。
? Type 是指你想查哪種信息,比如你想查這個(gè)域名對(duì)應(yīng)的IP地址是什么,那就是填A(yù)(address),如果你想查這個(gè)域名有沒(méi)有其他別名,就填CNAME(Canonical Name)。如果你想查 xiaobaidebug@gmail.com對(duì)應(yīng)的郵箱服務(wù)器地址是什么(比如 gmail.com),那就填MX(Mail Exchanger)。除此之外還有很多類型,下面是常見(jiàn)的Type表格。
? Class字段就比較有意思了,你可以簡(jiǎn)單的認(rèn)為,我們只會(huì)看到它填I(lǐng)N (Internet)。其實(shí)DNS協(xié)議本來(lái)設(shè)計(jì)出來(lái)是考慮到可能會(huì)有更多的應(yīng)用場(chǎng)景的,比如這里還能填CH,HS。大家甚至都不需要知道它們是什么含義,因?yàn)殡S著時(shí)間的發(fā)展,這些都已經(jīng)成化石了,我們知道這個(gè)字段的唯一作用,可能 就是可以在面試的時(shí)候可以隨意裝個(gè)x,深藏功與名。
Answers 字段,從名字可以看出,跟Queries對(duì)應(yīng),一問(wèn)一答 。作用是返回查詢結(jié)果,比如通過(guò)域名查對(duì)應(yīng)的IP地址,這個(gè)字段里就會(huì)放入具體的IP信息。
抓包
原理看完了,來(lái)抓個(gè)包吧。
我們打開(kāi)wireshark。然后執(zhí)行
digwww.baidu.com
此時(shí)操作系統(tǒng)會(huì)發(fā)出DNS請(qǐng)求,查詢 www.baidu.com對(duì)應(yīng)的IP地址。
DNS_Query
上面的圖里是DNS查詢(request)的內(nèi)容,可以看到它是應(yīng)用層的協(xié)議,傳輸層用的是UDP協(xié)議 進(jìn)行數(shù)據(jù)傳輸。截圖里標(biāo)紅的部分,也就是上面提到的需要重點(diǎn)關(guān)注的報(bào)文字段內(nèi)容。其中flag字段是按bit展示的,因此抓包里進(jìn)行了分行展示。
接下來(lái)再看下響應(yīng)(response)的數(shù)據(jù)包內(nèi)容。
DNS_Response
可以看到事務(wù)ID (Transaction ID)跟DNS請(qǐng)求 報(bào)文是一致的。并且Answers字段里帶有兩個(gè)IP地址。試了下,兩個(gè)IP地址都是可以正常訪問(wèn)的。
總結(jié)
? DNS是非常優(yōu)秀的高并發(fā)分布式系統(tǒng),通過(guò)層次結(jié)構(gòu)將服務(wù)進(jìn)行拆分 ,流量分散到多個(gè)服務(wù)器中。又通過(guò)加入多級(jí)緩存 ,讓每個(gè)層級(jí)實(shí)際接收到的緩存大大減小,因此大大提高了系統(tǒng)的性能。這兩點(diǎn)在做業(yè)務(wù)開(kāi)發(fā)的過(guò)程中是可以借鑒的。
? 插上網(wǎng)線通網(wǎng)時(shí),本機(jī)通過(guò)DHCP協(xié)議獲得DNS服務(wù)器的地址。
? 根域服務(wù)器的IP會(huì)以配置的形式加載到每一臺(tái)DNS服務(wù)器當(dāng)中。因此訪問(wèn)任意一臺(tái)DNS服務(wù)器都能輕松找到根域?qū)?yīng)的IP地址。
最后
最后給大家留下兩個(gè)問(wèn)題。
DNS基于UDP協(xié)議
? 從抓包可以看出,DNS在傳輸層上使用了UDP協(xié)議,那它只用UDP嗎?
? 上面提到,DNS的IPV4根域名 只有13個(gè),這里面其實(shí)有不少都部署在漂亮國(guó),那是不是意味著,只要他們不高興了,切斷我們的訪問(wèn),我們的網(wǎng)絡(luò)就得癱瘓了呢?
審核編輯:劉清
-
服務(wù)器
+關(guān)注
關(guān)注
13文章
9791瀏覽量
87920 -
DNS
+關(guān)注
關(guān)注
0文章
226瀏覽量
20442 -
URL
+關(guān)注
關(guān)注
0文章
141瀏覽量
15861 -
DHCP協(xié)議
+關(guān)注
關(guān)注
0文章
4瀏覽量
5063
原文標(biāo)題:DNS中有哪些值得學(xué)習(xí)的架構(gòu)設(shè)計(jì)
文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
評(píng)論