內容傳遞聯播網 (CDN)

使用內容傳遞網路來改善效能。

Katie Hempenius
Katie Hempenius

內容傳遞網路 (CDN) 使用分散式伺服器網路來為使用者提供資源,藉此改善網站效能。CDN 可以降低伺服器負載,因此能降低伺服器成本,非常適合處理突然增加的流量。本文探討 CDN 的運作方式,並提供各平台通用的指引,說明如何選擇、設定和最佳化 CDN 設定。

總覽

內容傳遞網路由經過最佳化處理的伺服器網路組成,能夠快速將內容傳遞給使用者。雖然 CDN 通常是以提供快取內容聞名,但還能改善無法快取內容的傳遞。一般來說,透過 CDN 放送的網站越多,

整體而言,CD 的效能優勢,其特色在於幾項原則:CDN 與來源伺服器相距較靠近使用者,因此往返時間 (RTT) 的延遲時間較短;相較於「直接」從來源伺服器載入內容,CD 傳遞內容的速度較快。此外,與 CDN 快取相比, CDN 快取更讓傳送內容的速度更快,不需向原始伺服器傳輸要求。

資源提供

雖然這聽起來似乎不符合直覺,但使用 CDN 提供資源 (即使是無法快取的資源) 通常會比讓使用者從伺服器「直接」載入資源的速度更快。

使用 CDN 傳遞來源資源時,系統會在用戶端與鄰近 CDN 伺服器之間建立新連線。流程的其餘部分 (也就是 CDN 伺服器和來源之間的資料移轉) 透過 CDN 的網路進行,通常包含來源的現有永久連線。這麼做的好處有兩個:盡可能從最靠近使用者的位置終止新連線,以避免不必要的連線設定費用 (建立新連線的費用昂貴,且需要多次往返);使用預先暖機連線,就能以最大處理量立即傳輸資料。

比較與非 CDN 的連線設定

有些 CDN 透過散佈至網際網路的多個 CDN 伺服器,將流量轉送至來源,進一步改善這一點。CDN 伺服器之間的連線是透過可靠且高度最佳化的路徑進行,而非由邊界閘道通訊協定 (BGP) 決定的路徑。雖然 BGP 是網際網路的實際轉送通訊協定,但其轉送決策並非一律以效能為導向。因此,BGP 判定路徑的效能可能不如 CDN 伺服器之間的經過微調路徑。

比較與非 CDN 的連線設定

快取

如果透過 CDN 伺服器快取資源,就不必將要求傳送到來源,就能直接獲得服務。因此,資源的傳送速度會較快,同時也能減少來源伺服器的負載。

將資源新增至快取

填入 CDN 快取時,最常用的方法是讓 CDN 視需求「提取」資源,這稱為「來源提取」。系統第一次向快取要求特定資源時,CDN 會向來源伺服器要求該資源,並快取回應。透過這種方式,系統就會在要求額外的未快取資源時持續建構快取內容。

從快取中移除資源

CDN 會使用快取清除功能,定期將不需要的資源從快取中移除。此外,網站擁有者可以使用清除功能來明確移除資源。

  • 快取撤銷

    快取有有限的儲存空間容量。快取接近容量時,系統會移除最近未存取的資源,或會佔用大量空間,藉此為新資源騰出空間。這項程序稱為快取移除。從一個快取中移除的資源不一定代表該資源已從 CDN 網路中的所有快取中移除。

  • 清除

    清除 (又稱為「快取撤銷」) 是一種從 CDN 快取中移除資源的機制,不必等待資源過期或被移除。通常透過 API 執行。在需要撤銷內容 (例如拼寫錯誤、定價錯誤或不正確的新聞報導) 的情況下,清除 - 非常重要。除此之外,在網站的快取策略中,

    如果 CDN 支援近乎即時清除功能,這項清除功能可做為管理動態內容的快取機制:使用較長的 TTL 快取動態內容,然後在資源更新時清除。如此一來,儘管無法事先得知資源何時會變更,仍可以將動態資源的快取時間最大化。這項技術有時稱為「滯留快取」。

    大規模採用清除作業時,通常會搭配「快取標記」或「代理快取金鑰」概念使用。這項機制可讓網站擁有者將一或多個額外 ID (有時稱為「代碼」) 與快取資源建立關聯。這些標記就能用於執行精細的資料清除作業。舉例來說,您可以在所有包含網站頁尾的資源 (例如 /about/blog) 中加入「footer」標記。頁尾更新完成後,請指示 CDN 清除與「footer」代碼相關聯的所有資源。

可快取的資源

資源快取的定義和方式取決於其為公開或私人、靜態或動態。

私人與公開資源
  • 私人資源

    私人資源包含適用於單一使用者的資料,因此不應由 CDN 快取。私人資源會以 Cache-Control: private 標頭表示。

  • 公開資源

    公開資源不含使用者專屬資訊,因此可由 CDN 快取。如果資源沒有 Cache-Control: no-storeCache-Control: private 標頭,則 CDN 可能會將資源視為可快取。公開資源可快取的時間長度,取決於資產變更的頻率。

動態和靜態內容
  • 動態內容

    動態內容是指經常變動的內容,API 回應和商店首頁都是這類內容的例子。不過,即使內容經常變更,也不一定會導致系統遭到快取。在流量較高的時段 (例如 5 秒) 快取這些回應可大幅減少來源伺服器的負載,同時盡量降低資料更新間隔的影響。

  • 靜態內容

    靜態內容偶爾會不常變更。圖片、影片和版本化程式庫通常是這類內容的例子。由於靜態內容不會變動,因此快取的內容應具有較長的存留時間 (TTL),例如 6 個月或 1 年。

選擇 CDN

選擇 CDN 時,效能通常是考量的重點。不過,當您選擇 CDN 時,請務必考量 CDN 提供的其他功能 (例如安全性和數據分析功能),以及 CDN 的定價、支援和新手上路流程。

效能

整體而言,CD 的效能策略需要考量在最短延遲時間與快取命中率之間,權衡取捨。具有許多服務點 (PoP) 的 CDN 可以縮短延遲時間,但由於流量會拆分至更多快取,因此快取命中率可能會較低。相反地,PoP 較少的 CDN 則可能位於更遠的地理位置,雖然使用者可能有更遠的地位,但也能達到更高的快取命中率。

基於這種取捨,部分 CDN 採用分層式快取方法,也就是由較靠近使用者 (又稱為「邊緣快取」) 的中央服務點補充,快取命中率較高的中央服務點 (PoP)。如果邊緣快取找不到某項資源,則會透過該資源的中央服務點 (PoP) 尋找資源。這種做法會稍微拉長延遲時間,因此更有可能從 CDN 快取提供資源,但不一定是邊緣快取。

想要盡量減少延遲時間和最大快取命中率,權衡利弊得失。在所有情況下,某種做法的成效並沒有一套比較好,不過,視您網站的性質和使用者群而定,以下其中一種方法的成效可能明顯較佳。

值得注意的是,CD 的效能可能會因地理位置、時段,甚至是當前事件而有極大差異。雖然建議您自行研究 CDN 的成效,但要預測 CDN 的實際成效並不容易。

對 Largest Contentful Paint (LCP) 的影響

如前所述,CDN 的主要用途是將資源分配給地理位置較靠近使用者的伺服器,以縮短延遲時間。因此,CDN 的主要優點在於能夠提高載入效能。具體來說,當您將 CDN 導入網站的伺服器端架構,可以大幅改善資源的首次位元組時間 (TTFB)

雖然 TTFB 不是以使用者為中心的成效指標,但透過最大內容繪製 (LCP) 診斷問題的重要指標,這個指標以使用者為中心。

CDN 能有效改善 LCP,因為這類技術可以改善文件傳遞作業的 TTFB (透過減少連線設定及快取文件的 TTFB),並改善轉譯 LCP 元素所需的任何靜態資源的推送成效。

其他功能

CDN 通常除了提供核心 CDN 服務外,通常還會提供各種功能。常見的功能包括負載平衡、圖片最佳化、影片串流、邊緣運算和安全性產品。

如何設定及設定 CDN

在理想情況下,您應該使用 CDN 來放送整個網站。整體而言,設定程序包含向 CDN 供應商申請,然後更新 CNAME DNS 記錄以指向 CDN 供應商。舉例來說,www.example.com 的 CNAME 記錄可能指向 example.my-cdn.com。這項變更生效後,您網站的流量會透過 CDN 轉送。

如果無法選擇使用 CDN 提供所有資源,您可以將 CDN 設定為僅提供部分資源,例如,僅提供靜態資源。方法是建立單獨的 CNAME 記錄,僅適用於 CDN 應提供的資源。舉例來說,您可以建立指向 example.my-cdn.comstatic.example.com CNAME 記錄。您也需要重新編寫 CDN 提供的資源網址,使其指向您建立的 static.example.com 子網域。

雖然現在 CDN 已在這個階段完成設定,但可能會有效率不彰的情形。本文接下來的兩節將說明如何提高快取命中率並啟用效能功能,以便發揮 CDN 的最大效益。

改善快取命中率

有效的 CDN 設定會盡可能從快取提供最多資源。這個值通常是以快取命中率 (CHR) 計算。快取命中率的定義為快取命中數除以特定時間間隔內的要求總數。

剛初始化的快取的 CHR 為 0,但隨著快取填入資源,這個值會增加。對大多數網站來說,CHR 為 90% 是很好的目標。CDN 供應商應為您提供有關 CHR 的分析和報表。

最佳化 CHR 時,首先需確認系統能否快取所有可快取資源,並達到正確的時間長度。所有現場都必須接受這項簡單的評估。

一般來說,CHR 最佳化功能的下一個層級是調整 CDN 設定,確保系統不會單獨快取邏輯相等的伺服器回應。這是由於查詢參數、Cookie 和要求標頭等因素所造成的影響,導致這常見的低效率。

初步稽核

多數 CDN 會提供快取分析。此外,WebPageTestLighthouse 等工具還能用來快速驗證網頁上的所有靜態資源,是否在正確的時間長度的快取資料。方法是檢查每個資源的 HTTP 快取標頭。使用合適的存留時間 (TTL) 快取資源可以避免日後發生不必要的來源擷取作業,進而增加 CHR。

一般來說,您必須設定下列其中一個標頭,CDN 才能快取資源:

  • Cache-Control: max-age=
  • Cache-Control: s-maxage=
  • Expires

此外,雖然這不會影響 CDN 快取資源的方式或方式,但建議您一併設定 Cache-Control: immutable 指令。Cache-Control: immutable 表示資源「在其更新生命週期期間不會更新」。因此,透過瀏覽器快取提供資源時,瀏覽器不會重新驗證該資源,因此不需要不必要的伺服器要求。很抱歉,只有 Firefox 和 Safari 支援這個指令,因為以 Chromium 為基礎的瀏覽器不支援這個指令。這項問題會追蹤對 Cache-Control: immutable 的 Chromium 支援情形。建議您加上星號這個問題,鼓勵更多人支持這項功能。

如需 HTTP 快取的詳細說明,請參閱使用 HTTP 快取避免不必要的網路要求

微調

稍微簡化了 CDN 快取的運作方式,就是使用資源的網址做為快取和擷取快取資源的金鑰。實務上,這仍是虛構的,但會稍加複雜,因為諸如要求標頭和查詢參數的影響而稍微複雜。因此,如要最大化 CHR 並確保向使用者提供正確的內容,重寫要求網址是相當重要的技術。設定正確的 CDN 執行個體,在過度精細的快取 (這會造成 CHR) 及精細的快取不足 (這會導致向使用者提供錯誤回應) 之間達到正確的平衡。

查詢參數

根據預設,CDN 會在快取資源時將查詢參數納入考量。不過,對查詢參數處理所做的微幅調整可能會對 CHR 造成顯著影響。例如:

  • 不必要的查詢參數

    根據預設,CD 會單獨快取 example.com/blogexample.com/blog?referral_id=2zjk,即使兩者可能是相同的基礎資源也一樣。請調整 CDN 的設定來忽略 referral\_id 查詢參數,藉此修正這個問題。

  • 查詢參數順序

    CDN 會從 example.com/blog?query=dogs&id=123 分開快取 example.com/blog?id=123&query=dogs。對於大多數網站,查詢參數順序並不重要,因此設定 CDN 來排序查詢參數 (透過將用來快取伺服器回應的網址標準化) 會增加 CHR。

變化

Vary 回應標頭會告知快取,根據要求所設定的標頭 (例如 Accept-LanguageAccept-Encoding 要求標頭),對應至特定網址的伺服器回應會有所不同。因此會指示 CDN 個別快取這些回應。Vary 標頭不受 CDN 廣泛支援,因此可能會導致快取無法提供可快取的資源。

雖然 Vary 標頭是相當實用的工具,但不當使用會損害 CHR。此外,如果您使用 Vary,將要求標頭正規化將有助於改善 CHR。舉例來說,如果沒有將要求標頭 Accept-Language: en-USAccept-Language: en-US,en;q=0.9 正規化,即使內容可能相同,系統還是會顯示兩個不同的快取項目。

餅乾

Cookie 是透過 Cookie 標頭設定的,是在回應上透過 Set-Cookie 標頭進行設定。由於快取通常不會快取包含此標頭的伺服器回應,因此應避免不必要的 Set-Cookie 標頭。

效能功能

本節說明 CDN 通常在核心產品服務中提供的效能功能。許多網站都忘記啟用這些功能,導致成效下滑。

壓縮

所有文字回應都應使用 gzip 或 Brotli 壓縮。你也可以選擇 Brotli,而非 gzip。與 gzip 相比,Britli 是較新的壓縮演算法,可以獲得更高的壓縮比例。

對 Brotli 壓縮功能支援兩種 CDN 類型,分別是「來源的 Brotli」和「自動 Brotli 壓縮」。

來自來源的 Brotli

來自來源的 Brotli 是指 CDN 提供來源未壓縮過的資源。雖然所有 CDN 應該都能立即支援,但 CDN 必須具備能夠快取與指定網址相對應的資源的多個版本,也就是 gzip 壓縮檔和 Brotli 壓縮檔。

自動壓縮 Brotli 格式

自動 Brotli 壓縮是指 CDN 壓縮資源的情況。CDN 可以壓縮可快取和非可快取的資源。

系統第一次要求資源時,使用「足夠」的壓縮方式提供資源,例如 Brotli-5。這種壓縮方式適用於可快取和非可快取的資源。

同時,如果資源可供快取,CDN 會透過離線處理,以更強大但速度變慢的壓縮等級 (例如 Brotli-11) 壓縮資源。這項壓縮完成後,系統會快取更多壓縮版本,並用於後續的要求。

壓縮最佳做法

如果要盡量提高效能,請在來源伺服器和 CDN 同時套用 Brotli 壓縮。來源中的 Brotli 壓縮能盡量減少無法從快取提供的資源傳輸大小。為了避免處理要求發生延遲,來源應以非常保守的壓縮等級 (例如 Brotli-4) 壓縮動態資源,靜態資源可以使用 Brotli-11 加以壓縮。如果來源不支援 Brotli,gzip-6 可用來壓縮動態資源;gzip-9 可用於壓縮靜態資源。

TLS 1.3

TLS 1.3 是傳輸層安全標準 (TLS) 的最新版本,也就是 HTTPS 使用的加密編譯通訊協定。與 TLS 1.2 相比,TLS 1.3 的隱私性和效能更佳。

TLS 1.3 可將 TLS 握手從兩次往返的時間縮短為一。如果是使用 HTTP/1 或 HTTP/2 的連線,只要將 TLS 握手縮短成一次往返的時間,就能有效縮短 33% 的連線設定時間。

比較 TLS 1.2 和 TLS 1.3 握手

HTTP/2 和 HTTP/3

HTTP/2 和 HTTP/3 都能提供比 HTTP/1 更卓越的效能優勢。其中,HTTP/3 能夠帶來更「潛力」的「潛在」效能優勢。HTTP/3 尚未完全標準化,但一旦達成這個目標,系統就會廣泛支援

HTTP/2

如果您的 CDN 預設未啟用 HTTP/2,建議您啟用此功能。HTTP/2 提供比 HTTP/1 更多的效能優勢,也是所有主要瀏覽器支援的。HTTP/2 的效能功能包括:多工處理串流優先順序標頭壓縮

  • 多工處理

    多工處理是 HTTP/2 最重要的功能多工處理可讓單一 TCP 連線同時提供多個要求/回應組合。這麼做可免除不必要的連線設定負荷,因為瀏覽器在一段時間內可開啟的連線數量有限,因此瀏覽器現在可以同時要求更多網頁資源。理論上來說,多工處理省去了串連和 Sprite 工作表等 HTTP/1 最佳化的需求。然而,實際上,由於較大的檔案壓縮得更好,因此這些技術在實務上仍具有關聯性。

  • 串流優先順序

    多工串流可啟用多個並行串流;串流優先順序提供一個介面,用於通訊各個串流的相對優先順序。因此,即使伺服器沒有先要求,也能優先傳送最重要的資源。

串流優先順序是由瀏覽器以相依樹狀結構表示,只是「偏好設定」陳述:換句話說,伺服器沒有義務達到 (或甚至考量) 瀏覽器設定的優先順序。當更多網站透過 CDN 放送時,串流優先順序會變得更有效率。

HTTP/2 資源優先順序的 CDN 實作方法有極大差異。如要確認您的 CDN 是否完全且正確支援 HTTP/2 資源優先順序,請參閱「HTTP/2 很快嗎?」一文。

雖然將 CDN 執行個體切換至 HTTP/2 絕大部分是切換切換開關的工作,但在您為 CDN 啟用變更之前,請務必先充分測試這項變更。HTTP/1 和 HTTP/2 對要求與回應標頭使用相同慣例,但在未遵循這些慣例的情況下,HTTP/2 就沒那麼容易了。因此,在啟用 HTTP/2 後,非規格的做法 (例如標頭包含非 ASCII 或大寫字元) 可能開始造成錯誤。發生這種情況時,瀏覽器嘗試下載資源時會失敗。開發人員工具的「網路」分頁會顯示失敗的下載嘗試。此外,控制台中也會顯示「ERR_HTTP2_PROTOCOL_ERROR」錯誤訊息。

HTTP/3

HTTP/3HTTP/2 的後續版本。截至 2020 年 9 月為止,所有主要瀏覽器都提供 HTTP/3 的實驗性支援,部分 CDN 則支援這種格式。HTTP/3 比 HTTP/2 的主要優勢在於效能。具體來說,HTTP/3 會消除連線層級的標頭阻斷,並縮短連線設定時間。

  • 消除線頭封鎖

    HTTP/2 導入了多工處理功能,可讓單一連線同時傳輸多個資料串流。然而,如果使用 HTTP/2,單一捨棄封包會封鎖連線中的所有串流 (稱為「線路封鎖」的現象)。使用 HTTP/3 時,捨棄的封包只會封鎖單一串流。這項改善主要是由於 HTTP/3 使用 UDP (HTTP/3 透過 QUIC 使用 UDP),而非 TCP 帶來的結果。因此,HTTP/3 特別適合用於在壅塞或有損網路傳輸的資料。

這張圖表顯示 HTTP/1、HTTP/2 和 HTTP/3 之間的資料傳輸差異
  • 縮短連線設定時間

    HTTP/3 採用傳輸層安全標準 (TLS) 1.3,因此具備相同效能優點:建立新連線只需要進行一次往返,而且恢復現有連線就不需進行任何往返作業。

比較 TLS 1.2、TLS 1.3、TLS 1.3 0-RTT 與 HTTP/3 之間的恢復連線比較

HTTP/3 會對網路連線品質不佳的使用者造成最大的影響:不僅因為 HTTP/3 處理封包遺失率優於先前情況,還因為處理 0-RTT 或 1-RTT 連線設定能省下大量時間,反而會拉長這類網路的延遲時間。

圖片最佳化

CDN 圖片最佳化服務通常著重於可自動套用的圖片最佳化功能,以縮減圖片傳輸大小。例如:移除 EXIF 資料、套用無損壓縮,並將圖片轉換為新的檔案格式 (例如 WebP)。網頁中的傳輸位元組約佔了圖片傳輸量的 50%,因此最佳化圖片可大幅縮減網頁大小。

壓縮

壓縮功能可移除 JavaScript、CSS 和 HTML 中的多餘字元。建議您使用原始伺服器 (而非 CDN) 進行壓縮。網站擁有者對要壓縮的程式碼有較多的背景脈絡,因此相較於 CDN 採用的技術,他們通常使用更積極的壓縮技術。不過,如果無法壓縮來源端的程式碼,建議您改用 CDN 壓縮。

結論

  • 使用 CDN:CDN 能快速推送資源、降低來源伺服器的負載,並有助於處理遽增的流量。
  • 盡可能以安全機制快取內容:可以且應該快取靜態和動態內容,但時間長度不一定相同。定期稽核網站,確保快取內容處於最佳狀態。
  • 啟用 CDN 效能功能:Britli、TLS 1.3、HTTP/2 和 HTTP/3 等功能可進一步改善效能。