閑話 CDN
來自專欄餓了么前端185 人贊了文章
開頭
這篇文章通過 FCC 上海線下和成都微信的分享,整理成文字稿順便湊一下更新,考慮到吃瓜讀者們不知道都了解到啥程度,以及我科普作者的身份(自己定的),我決定從入門到放棄的介紹一下,大致涉及:
- 什麼是 CDN
- 為什麼我們要用 CDN
- 訪問原理
- 架構
- 應用與踩坑
- 現實世界的 CDN
由於每個地方都事無巨細講起來非常費勁,費勁就容易跳票,而且會導致篇幅過長,所以其實都是科普向的,如果想要深入,在每個地方都會給出鏈接,可以進行針對性的深入閱讀。
如果有說的不對的地方請各位大佬指摘,粗體部分為超鏈接。
什麼是 CDN
從一個簡單的栗子說起:
「非洲農業不發達,人人都要金坷垃」——相信大家基本上都看過來自美國聖地亞哥的視頻,美國人、非洲人和日本人在一起搶來搶去。如果金坷垃只在一個地方生產,那麼非洲的運輸成本和生產者的產能壓力都很大。
那麼很簡單,我們在世界的每個需要金坷垃的國家都開代工廠,都生產金坷垃——我們的 CDN 就是生產金坷垃的公司,而一個個「節點」就是代工廠。
CDN,中文名叫做「內容分發網路」,它的作用是減少傳播時延,找最近的節點,實際上,儘管互聯網幫助我們實現了地球村,但是從中國到日本和從中國到台灣的時延仍舊是不一樣的,這一點可以從 ping 和 traceroute 中看出。
CDN 的優點
訪問加速
CDN 作為前端性能經典手段,相信大家已經無腦使用了,正如前面所說的,減少了時延,從很大程度上就能作為加速手段了。實際上,真正的 CDN 並不是前面舉例的一個國家一個節點,甚至是一個運營商,一個省份乃至地區都會有節點。
?
減輕源站(伺服器)負載
一個非常簡單就能想明白的問題,如果 CDN 已經能幫我返回數據了,那麼請求就不會到達源站,源站(伺服器)的負載就減輕了。
抗住攻擊
既然源站的負載被減輕了,那麼在受到 DDOS 攻擊的時候,也能談笑風生。
當年阮老師被 DDOS 鬧的滿城風雨,後來阮老師就把內容開始遷移到 GayHub……
然後本來我不用更新內容,就在最近,阮老師發布了一篇 DDOS 防禦指南,然後接著被攻擊,又癱瘓了,防禦指南中說自己受到了 CC,然後遷移到了騰訊雲,啪啪啪打了我的臉……當然,其實 CC 並沒有那麼難防禦,但是不在分享主題內容中,感興趣的可以之後聊……
受到阮老師啟發,於是我糊了一個架構圖,一個博客系統的思路圖,基本上和市面上的 Jekyll 和 Hexo 一樣,當時我的設想是,把評論之類的全部抽出來,這樣打的時候最多打掛評論之類的,對於博文本身不會有任何影響。後來我回去查了一下,發現這不就和市面上的一樣嘛——不錯!
那麼既然靜態資源能上 CDN,我們的 API,我們的 MVC 頁面能不能也上 CDN?答案是可以的,關鍵就是這個叫全站加速的東西。
啥玩樣兒?其實 CDN 就是一個緩存,區別只是這個緩存是放在網路服務提供商節點的。
最簡單的模型像這張圖,這張圖來自《大型網站技術架構 核心原理與案例分析》一書。
訪問原理
從我們發起請求,到到達 CDN 節點,到底經過了哪些東西,CDN 是怎麼加速我們的請求的呢?
?
這張圖也是網上找來的。
首先我們在地址欄鍵入一個網址,瀏覽器發現本地沒有關於這個網址的 DNS 緩存,所以向網站的 DNS 伺服器發起請求。
網站的 DNS 伺服器設置了 CNAME,指向了某個 CDN 伺服器,也就是我們常見的阿里雲、騰訊雲、Cloudflare 之類的,去請求 CDN 中的智能 DNS 均衡負載系統。
均衡負載系統解析域名,把對用戶響應最快的節點返回給用戶,然後用戶向該節點發出請求。
如果是第一次訪問該內容,CDN 伺服器會向源站請求數據並緩存,否則的話,直接在緩存節點中找到該數據,將請求結果發給用戶。
對於最簡單的 CDN 系統而言,只要一台 DNS 調度伺服器和一個節點伺服器即可,但在複雜的應用中,會存在多級緩存,多台 Cache 來協同工作。
這裡我之前在博客里寫過類似的內容(實際上就是摘抄的)
架設原理
如果你要架設一個 CDN,大概需要怎麼做?記住我們剛才介紹的內容,重點是,CDN 仍然是一個緩存。
?
拿來阿里雲 CDN 的架構圖口胡一下,我也沒有搭建過,如果解釋的不對請大家指出。
既然是緩存,那麼很明顯,也就是均衡負載加上緩存調度的搭配,根據我們剛才所說的訪問原理,其實主要的重點除了均衡負載與緩存外,就是一個中央的 DNS 調度器。
實際上,和計算機的多級緩存設計以及後端的多級緩存設計一樣,每一層的 cache 一級比一級大,可以存儲更多資源,但是響應一個比一個耗時,如果在 L1 中無法命中,那麼我們就會去 L2 找,L2 無法命中才會回到源站,這樣可以有效的避免回到源站過於頻繁的問題。
?
接下來這張圖,我就有點編不下去了,在阿里,主要使用 LVS + Tengine 做負載均衡,然後用 Swift 做 HTTP 緩存。這是他們自己說的,但是和我沒什麼關係,我主要講的是左邊那個花括弧的一致性 Hash。
一致性 Hash 就是把對象映射在 232 個桶空間里,像一個閉合的圓環,當然,實際上,我們將機器也映射到這個圓環中,比如利用別名或者 IP,順時針將對象將內容存儲到離自己最近的機器中,刪除和添加節點也一樣,添加和刪除節點之後,根據順時針遷移,原來的對象會進行重新計算。
關於這點需要詳細了解可以看這篇:https://blog.csdn.net/cywosp/article/details/23397179
?
然後說完這個關鍵性演算法,我們就差不多消化了——隔壁阿里雲 CDN 是怎麼搞出來的。
當然這依舊和我們沒啥關係……
應用與踩坑
最常見的應用,就是用於前端靜態資源的加速,實際上,利用 CDN,我們甚至可以做出一套屬於自己的 jsDelivr。
不過,使用 CDN 的時候,有一些基本法需要我們了解。
緩存設置
第一,緩存的設置,max-age 我們都用過,在 Cache-Control 中經常用於緩存的控制,可是 max-age 設置的緩存會應用於一個請求經過的每一級,如果我們希望 CDN 不緩存那麼久,要怎麼辦呢?那就是 s-maxage,它用於設置代理伺服器的緩存時間,會覆蓋 max-age 的設置,這樣我們可以把 max-age 用於本地緩存,把 s-maxage 用於 CDN 緩存時間,避免臟數據的產生。
緩存命中率
對於一個緩存而言,還有一點很重要,就是你的緩存到底有沒有用,衡量這個東西的就是緩存命中率。如果只是靜態資源,在刷新緩存之後,可能會導致命中率下降,因此 CDN 的資源不適合經常刷新,換句話說,如果一個請求結果會經常進行變更,那麼 CDN 基本就沒什麼存在的意義。
判斷是否命中緩存
無論是我們自己在開發過程中,還是幫客戶 debug 的過程中,我們都會考慮一件事——這個資源是否命中了CDN,是否是因為CDN導致的問題,這個時候就要秀一波操作了。
?
在各大廠商的 CDN 返回的數據中都會有一個 X-Cache,上面內容是 Hit 或者 Miss,還會加上諸如 Memory 或者 Disk 的縮寫表示內存還是磁碟,如果出現 Upstream 或者 Miss 則表示沒有命中。
資源預熱
緩存設計中,預熱是很重要的環節,在最初剛開始啟動 CDN 的時候,CDN 上並沒有緩存數據,此刻大量的請求全部打向源站,肯定會把源站打掛,預熱就是實現緩存好熱門數據,這樣在業務上線時,CDN 上已經有所需的數據了。
Vary
此外很多 CDN 都不支持 Vary 頭,這樣 CORS 需要的 Vary: Origin 就沒法保證了,遇到這種情況,比如你發現 Origin 頭被緩存了,就只能把跨域頭改為 * 去匹配。
Range
另外如果是很大的文件,往往是用 RANGE 頭分片載入的,但如果 CDN 沒有進行分片,就會重複向源站請求完整資源,CDN 就白搞了,啟用 RANGE 回源,就可以減少流量的損耗,正確的設置 RANGE 回源,就能夠正確的命中 CDN 緩存。
無私鑰 HTTPS
另外重點說一下:這年頭上 HTTPS 已經是常規基本法了,而不上 HTTPS 才是個噴點,CDN 為了避免篡改和劫持,當然也得上 HTTPS,但這樣就導致我們必須要將證書和私鑰傳輸到 CDN 的平台中去,對於安全性是一個隱患。
所以就有了無私鑰解決方案,用戶搭建私鑰伺服器,由 CDN 方去請求籤名。圖為阿里雲的實現,只要在自己的伺服器上部署 KeyServer 和配置就可以用了。
?
這裡我在上海 FCC 分享的時候有同學想要具體了解一下,具體來說的話涉及到很多 HTTPS 加密的事情,暫時不做展開,可以看一下 CloudFlare 發的一篇文章,我正好找到了翻譯版:https://www.zcfy.cc/article/keyless-ssl-the-nitty-gritty-technical-details-967.html
現實世界的 CDN
?比如,節點掛了,直接導致的是用戶的損失,尤其是體量大的公司依賴 CDN 進行靜態資源管理的時候,發生這樣的事情後果會非常嚴重。
其次,便宜沒好貨:本來在只有網宿而沒有阿里雲的時代,CDN 是很昂貴的,阿里騰訊在拉低 CDN 價格的同時,也拉低了 CDN 的質量,部分節點的訪問質量不太高會導致有些用戶訪問的網路質量非常差。
然後,一個微小的科普:什麼是混合 CDN——混合 CDN 這個名詞看著很高端,實際上就是,我們用了多家廠商的 CDN,可能也包括自己建的,然後誰好的選誰,但是有的時候反而會造成服務不可控,進一步劣化 CDN 的質量。
總結
CDN 這個東西本質就是一個緩存,只是這個緩存離你特別特別的近,作為用戶還是開發都能從中享受到一點福利,但作為一個服務於企業的開發人員,不僅要考慮 CDN 的優點,也要知道 CDN 給我們帶來的坑,這樣才能靠譜的作為 CDN 的使用者。
推薦閱讀:
※阿里雲E-HPC聯合安世亞太、聯科集團共建雲超算生態
※阿里雲免費使用及手冊——(免費卷領取技巧)
※利用阿里云云監控跟蹤和監控網站、雲伺服器宕機和運行狀態
※阿里雲-資料庫分散式文件系統研發專家-雲資料庫
※阿里雲總裁胡曉明:向亞馬遜發起全面挑戰