CDN 原理
CDN
CDN即內(nèi)容分發(fā)網(wǎng)絡(luò)(Content Delivery Network)的簡稱,是建立在承載網(wǎng)基礎(chǔ)上的虛擬分布式網(wǎng)絡(luò),能將源站內(nèi)容(包括各類動靜態(tài)資源)智能緩存到全球各節(jié)點服務(wù)器上。這樣不僅方便了用戶就近獲取內(nèi)容,提高了資源的訪問速度,也分擔(dān)了原站壓力。
加速域名
加速域名指需要使用CDN加速的域名。加速域名也是域名。加速域名一般配置CNAME記錄,指向CDN網(wǎng)絡(luò)節(jié)點。普通域名一般配置A記錄,指向提供服務(wù)的業(yè)務(wù)服務(wù)器。
CNAME記錄、A記錄和NS記錄
DNS(Domain Name System, 域名系統(tǒng))提供了將域名轉(zhuǎn)換為IP地址的服務(wù)。為了完成這個轉(zhuǎn)化工作,DNS的數(shù)據(jù)庫中需要維護(hù)相關(guān)數(shù)據(jù),這些數(shù)據(jù)被叫做RR(Resource Record,資源記錄)。資源記錄有很多種類型,比如A、NS、SOA、CNAME 和 PTR記錄。
大家接觸最多的就是A(Adress)記錄。A記錄是一條從域名到IP地址的映射記錄。而CNAME(Canonical Name)記錄是一條從域名到域名的映射記錄,它很好的實現(xiàn)的業(yè)務(wù)域名與CDN系統(tǒng)域名的解藕。簡單理解,如果一個域名配置了A記錄,DNS就會將它解析成A記錄對應(yīng)的IP地址。如果一個域名配置了CNAME記錄,DNS就會將他解析成CNAME記錄指定的另外一個域名。A記錄和CNAME記錄是互斥的,不能同時存在。CDN解析是個非常復(fù)雜的過程,詳細(xì)推薦查看DNS原理及其解析過程
NS(Name Server)記錄的是DNS服務(wù)器相關(guān)的一條記錄,它指定該域名應(yīng)該由哪一臺DNS服務(wù)器進(jìn)行解析。一般把通過NS記錄制定的DNS服務(wù)器叫做該域名的權(quán)威DNS服務(wù)器。
源站
提供原始資源(使用CDN加速的資源)的業(yè)務(wù)服務(wù)器,可以指定為域名或IP地址。
回源
CDN節(jié)點未緩存請求資源或緩存資源已到期時,回源站獲取資源,返回給客戶端。
工作原理
假設(shè)我建立了一個網(wǎng)站,域名為“www.marshall.com”,用戶訪問的主頁鏈接為“www.marshall.com/idx.html”。為了緩解服務(wù)端壓力和加快訪問速度,決定使用阿里云 CDN 服務(wù)。
為了更好地理解工作原理,先了解一下 CDN 的接入流程。
接入流程
主要接入步驟如下:
- 到某域名供應(yīng)商處申請一個加速域名:“js.marshll.com”。
- 到阿里云 CDN 平臺添加加速域名“js.marshll.com”,同時設(shè)置其源站域名為“www.marshll.com”
- 阿里云 CDN 平臺自動分配一個 CNAME 域名:“js.marshll.com.ali.com”。
- 到域名供應(yīng)商處給加速域名“js.marshall.com”添加 CNAME 記錄,其值為上一步得到的 CNAME 域名:“js.marshall.com.ali.com”。
對以上步驟做進(jìn)一步說明:
- 為了使用 CDN,必需另外再申請一個加速域名,作為使用 CDN 的入口。
- 加速域名配置的是 CNAME 記錄,值為 CDN 平臺提供的 CNAME 域名,該 CNAME 域名指向 CDN 系統(tǒng)節(jié)點。
- 添加加速域名時需要配置源站域名,據(jù)此,CDN 平臺保存了加速域名與源站域名的映射關(guān)系。
- CNAME 域名的格式一般是:<加速域名> + <供應(yīng)商主域名>
CDN系統(tǒng)架構(gòu)
從功能上看,典型的CDN系統(tǒng)由分發(fā)服務(wù)系統(tǒng)、負(fù)載均衡系統(tǒng)和運營管理系統(tǒng)組成。分發(fā)服務(wù)系統(tǒng)主要負(fù)責(zé)資源的響應(yīng)、緩存和同步。負(fù)載均衡系統(tǒng)主要負(fù)載對用戶請求進(jìn)行調(diào)度。運營管理系統(tǒng)則負(fù)責(zé)運營需求管理和網(wǎng)絡(luò)系統(tǒng)管理。
從節(jié)點分布上看,CDN系統(tǒng)主要分為邊緣層和中心層。邊緣層分布在CDN網(wǎng)絡(luò)的邊緣位置,給用戶提供就近訪問服務(wù)。中心層則負(fù)責(zé)完成資源同步和運營管理等功能。
中心層保存了加速域名的相關(guān)配置信息,比如源站域名,也緩存了加速域名下的各種資源。在邊緣層節(jié)點未命中緩存時,需要向中心層節(jié)點發(fā)起請求。而中心層節(jié)點未能命中緩存時,需要查找對應(yīng)的源站域名,并向該源站域名發(fā)起請求,然后再逐層返回并緩存用戶請求的資源。
訪問流程
當(dāng)用戶第一次訪問的流程如下圖1所示

需要進(jìn)一步說明的是:
- 第 1 步訪問的是加速域名,而不是源站域名。
- 第 3 步返回 CNAME 域名。
- 第 5 步返回 CNAME 域名對應(yīng)的 IP 地址,指向 CDN 邊緣層節(jié)點。
- 第 6 步請求的 URL (或者說 Referer )仍為‘js.marshall.com/idx.html’。
- 第 7 步請求中心層節(jié)點時,會帶上第 6 步的 URL 作為參數(shù)。
- 第 8 步通過查詢配置數(shù)據(jù)得到源站域名,進(jìn)而向源站發(fā)起請求。這里的業(yè)務(wù)服務(wù)器即為 CDN 的源站。簡單起見,省略了從 DNS 服務(wù)器查詢 A 記錄的過程。
- 在整個過程中,URL 的域名會變化,但是 URL 的路徑不會變化。

需要進(jìn)一步說明的是:
- 由于本地 DNS 客戶端擁有了加速域名的解析緩存,就不需要再查詢 DNS 服務(wù)器了。
- 由于 CDN 邊緣層節(jié)點有了對應(yīng)資源的緩存,就不需要再向上請求資源了。

需要進(jìn)一步說明的是:
- 由于用戶 A 和用戶 B 地域相差比較遠(yuǎn),使用不同的邊緣層節(jié)點,所以邊緣層節(jié)點沒有對應(yīng)資源的緩存,需要向中心層節(jié)點請求資源。
- 中心層節(jié)點擁有該資源的緩存,所以就不需要回源了。
就近訪問原理
CDN系統(tǒng)是如何實現(xiàn)就近訪問的呢?
CNAME域名是CDN供應(yīng)商提供的,CDN供應(yīng)商擁有對CNAME域名的配置權(quán)。CDN供應(yīng)商會把CNAME域名的NS記錄設(shè)置為自己搭建的DNS服務(wù)器。這樣一來,解析 CNAME 域名的時候就會請求 CDN 供應(yīng)商搭建的 DNS 服務(wù)器。而 CDN 供應(yīng)商在 DNS 服務(wù)器中實現(xiàn)了負(fù)載均衡,會返回離用戶較近的邊緣層節(jié)點的 IP 地址。如此便實現(xiàn)了就近訪問。
CNAME驗證
域名“a1.pstatp.com”, “a3.pstatp.com”, “a6.pstatp.com”分別是用于網(wǎng)宿、阿里云和金山云的 CDN 服務(wù)的加速域名。用 dig 命令來查看它們的 CNAME 記錄,分別為為“a1.pstatp.com.wscdns.com”、“a3.pstatp.com.w.alikunlun.net“和”a6.pstatp.com.download.ks-cdn.com“,與預(yù)期相符。



從路徑反推源站 IP 地址
我們并不知道源站 IP 地址是多少,因為不是我們配置的。因為在訪問過程中路徑是不會變的,可以根據(jù)路徑從 LB(Load Balancing,負(fù)載均衡)配置中反推源站 IP。從安全考慮,源站 IP 是保密信息,下面會對敏感信息進(jìn)行打碼。
以https://a3.pstatp.com/inapp/lib/raven.js請求為例子,




通過VIP訪問
可以在提供CDN服務(wù)的廠商處查詢源站的VIP(虛擬IP),然后進(jìn)行訪問。
由于是 VIP,所以必需加上 Host 信息才能訪問(VIP 也是保密信息,此處省略),比如
curl -H "Host: a3.pstatp.com" http://x.x.x.x/inapp/lib/raven.js
執(zhí)行后也是可以成功請求的資源的。
那么什么事VIP呢?我們理解的一般是真實 IP,即一個 IP 地址對應(yīng)一臺電腦。更專業(yè)一點說,就是一個 IP 地址對應(yīng)一個 MAC 地址。IP 地址到 MAC 地址的映射是由ARP協(xié)議實現(xiàn)的。VIP不是與某個固定的 MAC 地址映射的,而是與一群 MAC 地址中的某個 MAC 地址映射的。具體指向哪個 MAC 地址根據(jù)當(dāng)時的場景決定。也就是說,VIP 是一個邏輯 IP,而不是實體 IP。VIP 主要是用來實現(xiàn)網(wǎng)絡(luò)地址轉(zhuǎn)換,網(wǎng)絡(luò)容錯和可移動性,在云和負(fù)載均衡技術(shù)中有重要的應(yīng)用。
前端頁面部署
前端頁面相關(guān)的都是靜態(tài)資源,現(xiàn)在基本都走 CDN。在對前端頁面進(jìn)行部署時,需要上傳 CDN。
HTML文件部署
HTML 文件已經(jīng)被上傳到回源服務(wù)器上,可以通過 CDN 來訪問 HTML 文件了。前端頁面部署工作是不是就結(jié)束了?顯然沒這么簡單。
CDN 緩存有效地提升了訪問速度,但是也帶來了文件無法及時更新的問題。一般通過 Hash 字符串的方式來解決這個問題。在每個文件名后面加一個 hash 字符串,每次發(fā)布的靜態(tài)資源的文件名都不一樣,相應(yīng)的訪問 URL 也不一樣,這樣就不會命中緩存。這種方式對 CSS 和 JS 文件很好使,但是對 HTML 文件就不合適了。CSS 和 JS 文件名是寫在 HTML 文件中的,文件名的替換由 Webpack 自動完成的。用戶訪問某個網(wǎng)站時,一般會重定向到主頁面。也就是說,HTML 文件名一般是重定向時決定的,需要在重定向的路由中配置,比如 nginx 配置文件,替換工作基本手動完成。每次發(fā)布后都需要手動修改 nginx 配置,才能使用戶訪問最新的 HTML 文件,這顯然是不可行的。所以,Hash 字符串的辦法不適用于 HTML 文件。
因此,HTML 文件需要另外部署。
與服務(wù)端混合部署
早期的一種解決方案是把 HTML 文件放到服務(wù)端工程里面,與服務(wù)端服務(wù)一起部署。服務(wù)端服務(wù)是一個運行的服務(wù),可以提供對 HTML 文件的訪問。每次需要訪問新的 HTML 文件時,把服務(wù)端工程里面的 HTML 文件替換成新的文件,然后再重啟服務(wù)就可以了。
混合部署的缺點:
- 發(fā)布速度慢,受制于后端服務(wù)的發(fā)布
- 前后端工程耦合,不利于項目的維護(hù),也不利于部署管理
獨立部署
單獨給前端頁面起一個頁面服務(wù),同時提供管理服務(wù)來管理這些頁面服務(wù)。該頁面服務(wù)只提供訪問 HTML 文件的功能,不實現(xiàn)其他業(yè)務(wù)功能。
獨立部署的優(yōu)點:
- 發(fā)布速度快
- 功能聚焦,便于管理