CDN 為什么這么設(shè)計(jì)?
過去幾十年,計(jì)算機(jī)網(wǎng)絡(luò)把幾乎全世界的計(jì)算機(jī)都連接了起來(lái),我們只要把靜態(tài)資源和動(dòng)態(tài)的代碼部署到服務(wù)器上,然后啟動(dòng)服務(wù)監(jiān)聽某個(gè)端口,這樣世界各地的計(jì)算機(jī)就都能訪問該網(wǎng)站。
但是這樣有個(gè)問題,資源最終還是通過物理層網(wǎng)絡(luò)線路和設(shè)備傳輸?shù)?,每?jīng)過一段線路、一個(gè)網(wǎng)絡(luò)設(shè)備都有一些耗時(shí),所以客戶端和服務(wù)器相距越遠(yuǎn),網(wǎng)站打開速度就越慢。
這就像你從海南買了一件東西,如果你人在廣州的話,那可能很快就收到了,因?yàn)閭鬏斁嚯x近,但如果你在北京的話,那可能就要多等幾天了,因?yàn)橹虚g經(jīng)過的線路、節(jié)點(diǎn)都比較多。
但這樣肯定不行的,用戶體驗(yàn)會(huì)很差。怎么解決這個(gè)問題呢?
離得越遠(yuǎn)網(wǎng)站打開速度就越慢,很容易想到,如果部署到很多個(gè)地方,當(dāng)用戶訪問網(wǎng)絡(luò)的時(shí)候,訪問最近的那個(gè)不就行了?
這就像快遞都有一些中轉(zhuǎn)的倉(cāng)庫(kù),可以存放一些貨物,如果你人在北京,要買一個(gè)海南的東西,恰好北京的倉(cāng)庫(kù)里有,那豈不是很快就可以收到了。
思路是沒問題,但是怎么實(shí)現(xiàn)呢?
用戶是通過域名訪問網(wǎng)站的,那能不能通過 DNS 服務(wù)器來(lái)實(shí)現(xiàn)這個(gè)功能呢?
前面寫過一篇 ??DNS 原理的文章??,這里簡(jiǎn)單回顧下:
客戶端訪問某個(gè)域名的時(shí)候,會(huì)先查找本地 hosts 文件,如果能查到 ip 就直接訪問。
否則會(huì)向本地 DNS 服務(wù)器發(fā)請(qǐng)求,這個(gè)是聯(lián)通、移動(dòng)等運(yùn)營(yíng)商提供的每個(gè)城市都有的 DNS 服務(wù)器。由它去域名服務(wù)器發(fā)送解析域名的請(qǐng)求,然后把結(jié)果返給客戶端。
域名是分層解析的,有根域名服務(wù)器、頂級(jí)域名服務(wù)器、權(quán)威域名服務(wù)器三層,比如 image.baidu.com 會(huì)先向根域名服務(wù)器發(fā)請(qǐng)求查詢 com 的頂級(jí)域名服務(wù)器的 ip,然后再向 com 頂級(jí)域名服務(wù)器查詢 image.baidu.com 的權(quán)威域名服務(wù)器的 ip。查詢到權(quán)威域名服務(wù)器之后,任意層級(jí)的域名都會(huì)在這里解析(所以叫權(quán)威域名服務(wù)器)。
看到這個(gè)權(quán)威域名服務(wù)器的時(shí)候,不知道大家是否就想到怎么實(shí)現(xiàn) CDN 網(wǎng)絡(luò)了。
能不能在權(quán)威域名服務(wù)器這一層根據(jù)客戶端的 ip 做一下負(fù)載均衡呢?比如北京來(lái)的 DNS 請(qǐng)求就返回北京機(jī)房的服務(wù)器的 ip,上海來(lái)的 DNS 請(qǐng)求就返回上海機(jī)房的服務(wù)器的 ip。
確實(shí)可以這樣實(shí)現(xiàn)內(nèi)容的就近分發(fā),這樣的負(fù)載均衡網(wǎng)絡(luò)就叫做 CDN (Conent Delivery Network)
但是實(shí)現(xiàn)這樣一個(gè) CDN 網(wǎng)絡(luò)需要在全國(guó)建立多個(gè)機(jī)房,成本太高了,所以只有像百度、阿里、騰訊這類大公司才會(huì)自建 CDN,一般情況下我們都會(huì)買第三方的 CDN 服務(wù)來(lái)用。
這些公司建好了 CDN 網(wǎng)絡(luò),實(shí)際上自己也是用不完的,也會(huì)對(duì)外提供 CDN 加速服務(wù)。
第三方的 CDN 服務(wù)自然也要提供一個(gè) DNS 服務(wù)器,也就是實(shí)現(xiàn)根據(jù) ip 返回不同城市的服務(wù)器的 ip 的那個(gè)。
比如這是百度云 CDN 的原理圖:
用戶向本地 DNS 服務(wù)器發(fā)請(qǐng)求之后,經(jīng)歷根域名、頂級(jí)域名的 DNS 解析,最終會(huì)轉(zhuǎn)給權(quán)威 DNS 服務(wù)器。這時(shí)候只要權(quán)威 DNS 服務(wù)器再轉(zhuǎn)給 baidu 的 DNS 服務(wù)器就可以了,這樣就能接入 CDN 服務(wù)。
baidu 的 DNS 服務(wù)器實(shí)現(xiàn)了負(fù)載均衡,會(huì)根據(jù)請(qǐng)求 ip 所在的城市,返回不同城市的服務(wù)器的 ip。也就實(shí)現(xiàn)了就近分發(fā)的網(wǎng)絡(luò)加速功能。
那這個(gè)從權(quán)威 DNS 到 baidu 的 DNS 的轉(zhuǎn)發(fā)是怎么實(shí)現(xiàn)的呢?
DNS 的記錄有很多種類型,比如:
A 代表 address,記錄域名對(duì)應(yīng)的 ip。
CNAME 代表域名還有一個(gè)別名,可以向那個(gè)域名來(lái)查 ip。
MX 代表件名后綴對(duì)應(yīng)的域名或者 IP
看到這個(gè) CNAME 類型,大家應(yīng)該就想到怎么實(shí)現(xiàn)轉(zhuǎn)發(fā)了。
只要自己在 DNS服務(wù)器上配一條 CNAME 的記錄,指向 CDN 服務(wù)器的域名就可以了。
比如你用某云的 CDN 的時(shí)候,第一步也是要配置下自己的 DNS 服務(wù)器的 CNAME 指向它:
這樣,當(dāng)你訪問某個(gè)域名的時(shí)候,解析域名的權(quán)威服務(wù)器會(huì)返回 CDN 服務(wù)的 DNS 服務(wù)器的域名,然后再向這臺(tái) CDN 的 DNS 服務(wù)器發(fā)送解析域名的請(qǐng)求,這時(shí)候它就可以根據(jù) ip 所在城市來(lái)返回一個(gè)就近城市的服務(wù)器給你。
當(dāng)然,也可以再做一層 CNAME 轉(zhuǎn)發(fā),比如 CDN 的 DNS 服務(wù)器把域名解析轉(zhuǎn)給城市的 DNS 服務(wù)器,然后城市的 DNS 服務(wù)器再根據(jù)不同機(jī)器的負(fù)載情況來(lái)返回一臺(tái)離得近而且負(fù)載比較小的服務(wù)器的 ip 給客戶端。
這樣客戶端就能從最近的服務(wù)器下載靜態(tài)資源,從而更快地打開網(wǎng)站。
如果訪問的資源沒有的時(shí)候,會(huì)向源站服務(wù)器發(fā)請(qǐng)求來(lái)拿對(duì)應(yīng)的資源并且緩存下來(lái),之后再此訪問就不用訪問源站了。
這個(gè)緩存時(shí)間是怎么指定的呢?
CDN 服務(wù)會(huì)有一個(gè)控制臺(tái),可以設(shè)置不同資源的緩存時(shí)間,當(dāng)然,請(qǐng)求的 header 里也有 expries 和 Cache-Control 來(lái)控制緩存時(shí)間,這倆的生效的優(yōu)先級(jí)也是可以設(shè)置的。
這樣的 CDN 服務(wù)國(guó)內(nèi)和國(guó)外是分開的,如果網(wǎng)站目標(biāo)用戶只是國(guó)內(nèi)的,那只需要買下國(guó)內(nèi)的 CDN 服務(wù),國(guó)外用戶訪問慢點(diǎn)就慢點(diǎn),如果網(wǎng)站國(guó)外用戶也很多,那還需要買下國(guó)外的 CDN 服務(wù)。
比如某云的國(guó)內(nèi) CDN 節(jié)點(diǎn)分布是這樣的:
海外的話則是另一套 CDN 網(wǎng)絡(luò):
總結(jié)
為了加快網(wǎng)站打開速度,我們會(huì)使用 CDN 服務(wù),它并不是一個(gè)網(wǎng)絡(luò)協(xié)議,只是基于 DNS 協(xié)議實(shí)現(xiàn)的加速功能的網(wǎng)絡(luò)。
它的原理就是域名的權(quán)威 DNS 服務(wù)器把請(qǐng)求轉(zhuǎn)給 CND 的負(fù)載均衡的 DNS 服務(wù)器,然后根據(jù) ip返回不同城市的 DNS 服務(wù)器,再根據(jù)負(fù)載來(lái)選擇一臺(tái)就近的服務(wù)器 的 ip 返回。
這樣客戶端就能從最近的負(fù)載最小的服務(wù)器拿到資源。
CDN 的緩存設(shè)置可以根據(jù) header 來(lái),也可以在控制臺(tái)設(shè)置一些規(guī)則,這兩者生效的優(yōu)先級(jí)也可以設(shè)置。
CDN 網(wǎng)絡(luò)的建設(shè)成本還是很大的,只有大公司會(huì)自建,一般我們都會(huì)買三方服務(wù),而且國(guó)內(nèi)和海外的 CDN 都是分開的,如果主要服務(wù)國(guó)內(nèi)用戶,那只買國(guó)內(nèi)的 CDN 服務(wù)即可。
有了這套覆蓋全國(guó)、全球的 CDN 節(jié)點(diǎn)網(wǎng)絡(luò)之后,我們才能更快地打開網(wǎng)站。