當前位置:
首頁 > 知識 > 搭建自己的 CDN 的樂趣和好處

搭建自己的 CDN 的樂趣和好處

搭建自己的 CDN 的樂趣和好處

Python部落(python.freelycode.com)組織翻譯,禁止轉載,歡迎轉發。

如你所見,我也喜歡頁面能快速載入,越快越好.但在我們開始討論之前,先要有一個清楚的認知:CDN 並不是萬能的.如果因為糟糕的前端工作導致你的網站變慢,CDN 並不能幫到你太多,你需要先做好前端工作.但一旦你已經做好了所有的優化,就需要來研究一下內容傳輸這塊了.

我碰到的主要問題是即使能通過一次 HTTP 請求來完成初始網站的載入,但因為我的伺服器託管在法蘭克福,在澳大利亞的人仍需要等待2-3秒後才能訪問到它.超過300ms的往返延時和中間大量的服務提供商使得頁面載入就跟 WordPress 網站一樣慢.

那如何解決這個問題呢? 一種解決方案是使用傳統的 CDN.然而大多數商業 CDN 在從伺服器請求到數據之後,都會緩存一段時間.

搭建自己的 CDN 的樂趣和好處

由於 CDN 的存在,在內容獲取上稍微繞行了一下,導致在使用傳統 CDN 之後,初始頁面的載入反而變慢了.如果你的網站流量高,內容一直緩存著,這沒什麼大問題.但反過來說,如果和我一樣僅僅是運行一個小博客,內容並不會常駐緩存,傳統的 pull-CDN 反而會讓網站變得更慢.當然,我也可以通過 push-CDN 直接上傳內容,但跟我要搭建的 CDN 相比,這種成本要昂貴許多.

CDN 是如何工作的?

我們的方案很明確:為了擴大世界影響力,我們應該保證內容在任何位置都能被快速訪問.這意味著內容所在位置應該盡量靠近訪問者.方便的是,很多雲服務商在多個地區都提供了廉價的虛擬伺服器.我們是否僅需要把內容放到比如6台伺服器上,就萬事大吉了呢?

好吧,沒那麼快.那如何把用戶路由到正確的伺服器上呢?我們看一下實際訪問網站的過程.首先,瀏覽器通過 DNS 查詢網站的 IP 地址,獲取到 IP 之後,就可以連接網站並下載請求的頁面.

搭建自己的 CDN 的樂趣和好處

上層的解決方案其實很簡單:需要一台智能 DNS 伺服器,對請求的IP 做 GeoIP 查詢並返回離它最近的 IP 地址.事實上,幾乎所有的商業 CDN 都是這麼做的.雖然還牽扯到許多工程學領域的內容,比如延遲測量等,但基本原理還是這個.

讓 DNS 伺服器快起來

接下來新的問題出現了:如何讓 DNS 伺服器快起來?從最近節點上訪問網站僅僅解決了一半問題,如果 DNS 查找不得不繞行地球一周,還是會有極大的延遲.

事實證明,支撐互聯網的基礎設施非常適合解決這個問題.網路提供商使用邊界網關協議來相互告知可連接的網路和躍點的多少.多數情況下,最終互聯網提供商會採用最短路線來到達目標地址.

如果在多個位置使用一個 IP 地址,DNS 總是會路由到最近的節點,這就是 BGP Anycast.

為何網站下載不使用 BGP Anycast?

如果能做到,我們為何不簡單使用 BGP 來路由網路流量呢?主要有三個原因.

首先,使用 BGP Anycast 需要在網路硬體上做控制,並且需要一個至少包含256個 IP 地址的池子,這超出了我們的預算.

其次,BGP 路由並不那麼穩定.不同於 DNS 請求僅僅只需要向兩個方向發送單個數據包,HTTP web 請求需要創建一個連接來下載內容.期間如果路由改變或者連接不穩定,HTTP 連接就會斷開.對這種規模的工程來說反而增加了很多複雜性.

最後,躍點作為 BGP 路由計算基礎,它數目的減小並不能保證往返延遲的減小.一個跨大洋的躍點可能僅僅是一個躍點,但卻是時間最長的一個.


擴展閱讀: 關於這個話題,Linkedin Engineering上有一篇非常棒的博文

創建 DNS

既然已經確認不能運行我們自己的 BGP Anycast,也意味著同樣不能運行我們自己的 DNS 伺服器.讓我們去找找收費的!...事實證明,同時提供 BGP Anycast 和延遲路由的 DNS 提供商很難找到.我只搜索到了2個:相當昂貴的 Dyn 和非常便宜的 Amazon Route53.(更新:後來發現, DNS Made Easy 也能實現延遲路由)既然想合算,就選 Route53 了.添加域名之後開始為機器設置 IP. 我們需要設置跟我們遍布世界各地的(邊緣節點)伺服器同樣多的 DNS 記錄,每條記錄設置如下:

搭建自己的 CDN 的樂趣和好處

提示:最好對每個邊緣節點都創建一個健康檢查以便在他們失效後進行移除.

分發內容

我們需要解決的下一個問題是分發內容.每個邊緣節點都需要有相同的內容.如果你使用的是 Jekyll 這樣的靜態網站生成器,工作很簡單:只需要將生成的 HTML 文件複製到所有的伺服器上即可.一個簡單的 rsync 就能搞定.

如果想使用 WordPress 這樣的內容編輯系統,工作會困難的多,因為它並不能在 CDN 上運行.當然也可以做,但免不了有缺陷,靜態內容的分發仍然是一個問題.你可能必須要創建一個分散式存儲才能正常工作.

使用 SSL/TLS 證書

下一個痛點是使用 SSL/TLS 證書.實際上,可以統稱他們為:x509證書.每個邊緣節點都需要為域名設置有效的證書.當然,最簡單的解決方案是使用 LetsEncrypt 來生成不同的證書.但要注意, 我在其中一個邊緣節點上碰上了 LE 有效期的問題,導致在每周限額到期之前我不得不暫時把倫敦節點下掉.

我使用 Traefik 作為我的選擇代理, 它支持分散式鍵值存儲,甚至支持 Apache Zookeeper 後端同步.雖然這需要一些程序設計,可從長遠來看會更穩定一些.

結果

是時候檢驗一下結果了,我的 CDN 表現如何呢?使用這個工具,看一下總體數據:

搭建自己的 CDN 的樂趣和好處

如你所見,相當不錯的結果.我可能還需要在亞洲和南美加兩個節點來優化載入時間.

更新:在把它提交到 Hacker News 首頁之後,我可以使用 Google Analytics 來收集一些實際使用數據:

搭建自己的 CDN 的樂趣和好處

結論:我確實需要一個新加坡節點.在印度的載入時間超過了預期的1秒.

常見問題

我在做這項工作的時候,人們經常問我:"你為什麼要做這個呢?你這是自尋煩惱啊 ". 確實,在某種程度上,我喜歡做不同的事情來探索新方向和新技術,建立自己的 CDN 可能具有很大的意義.讓我們來談談關於設置的一些問題.

首先申明:如果商業提供商能推出價格合理的 push CDN,讓我能處理 nice URLs, SSL 和自定義頭信息,我絕對樂意花錢解決問題並停掉我自己的基礎設施.搭建它很有趣,但我還有很多伺服器沒有運行它.

為何不用 CloudFlare?

對很多人來說 CloudFlare 是一個很棒的工具,但如上所述, CDN 會從緩存中移除未使用的內容.我管理的其他網站,在正確配置的情況下緩存命中率大概能達到75%.擁有自己的 CDN 則意味著內容會常駐緩存,不會有訪問遠程伺服器而導致的往返延時.

為何不用 S3 或 CloudFront?

Amazon S3有託管靜態網站的選項,並且可以與 CloudFront 結合著使用.然而,它不允許你自定義緩存頭信息,設置 nice URLs等.為此,你需要使用 Lambda@Edge, 這是一個可以讓你在 CloudFront 邊緣節點上運行代碼的工具.但Lambda@Edge 跟 CDN 有同樣的問題:如果它在一段時間內沒有接收到請求,運行它的容器就會關閉,再次重啟則需要一秒鐘的時間.

為何不用 Google AMP?

Google AMP 只會在用戶通過 Google 搜索引擎訪問你的網站時才會帶來效果. 而我的大部分流量並非來自 Google, 所以它並不能解決問題. 它僅僅對 Google 有效果,不管其他. 而且我完全有能力在不使用他們提供的簡化 HTML 的情況下搭建一個快速網站.

誰在意? 3秒的載入時間已經很棒了!

我是一個擅長內容傳輸的 DevOps 工程師. 不管其他人如何,我都應該有一個全球都能快速訪問的網站,不是嗎?我一般都會將 Google AMP關閉,因為跟他們所期望的不同,這是一項糟糕的技術.

搭建

現在看你的了:是否要搭建你自己的 CDN? 源代碼在 GitHub 上,拿去吧!


英文原文:https://pasztor.at/blog/building-your-own-cdn
譯者:郭明

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python部落 的精彩文章:

程序員春節期間應該做的幾件事
2018 年學習 Python 的理由

TAG:Python部落 |